diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index fcfb297d50aa8..d62f87de61af4 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -328,7 +328,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { if let Some(annotation_index) = constant.user_ty { if let Err(terr) = self.cx.relate_type_and_user_type( constant.const_.ty(), - ty::Variance::Invariant, + ty::Invariant, &UserTypeProjection { base: annotation_index, projs: vec![] }, locations, ConstraintCategory::Boring, @@ -451,7 +451,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { if let Err(terr) = self.cx.relate_type_and_user_type( ty, - ty::Variance::Invariant, + ty::Invariant, user_ty, Locations::All(*span), ConstraintCategory::TypeAnnotation, @@ -1095,7 +1095,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ) -> Result<(), NoSolution> { // Use this order of parameters because the sup type is usually the // "expected" type in diagnostics. - self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category) + self.relate_types(sup, ty::Contravariant, sub, locations, category) } #[instrument(skip(self, category), level = "debug")] @@ -1106,7 +1106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution> { - self.relate_types(expected, ty::Variance::Invariant, found, locations, category) + self.relate_types(expected, ty::Invariant, found, locations, category) } #[instrument(skip(self), level = "debug")] @@ -1146,7 +1146,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { trace!(?curr_projected_ty); let ty = curr_projected_ty.ty; - self.relate_types(ty, v.xform(ty::Variance::Contravariant), a, locations, category)?; + self.relate_types(ty, v.xform(ty::Contravariant), a, locations, category)?; Ok(()) } @@ -1248,7 +1248,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(annotation_index) = self.rvalue_user_ty(rv) { if let Err(terr) = self.relate_type_and_user_type( rv_ty, - ty::Variance::Invariant, + ty::Invariant, &UserTypeProjection { base: annotation_index, projs: vec![] }, location.to_locations(), ConstraintCategory::Boring, diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index c531c9b209be5..b9a82046e59ad 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -50,14 +50,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory<'tcx>, ) -> Result<(), NoSolution> { - NllTypeRelating::new( - self, - locations, - category, - UniverseInfo::other(), - ty::Variance::Invariant, - ) - .relate(a, b)?; + NllTypeRelating::new(self, locations, category, UniverseInfo::other(), ty::Invariant) + .relate(a, b)?; Ok(()) } } @@ -106,15 +100,15 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { fn ambient_covariance(&self) -> bool { match self.ambient_variance { - ty::Variance::Covariant | ty::Variance::Invariant => true, - ty::Variance::Contravariant | ty::Variance::Bivariant => false, + ty::Covariant | ty::Invariant => true, + ty::Contravariant | ty::Bivariant => false, } } fn ambient_contravariance(&self) -> bool { match self.ambient_variance { - ty::Variance::Contravariant | ty::Variance::Invariant => true, - ty::Variance::Covariant | ty::Variance::Bivariant => false, + ty::Contravariant | ty::Invariant => true, + ty::Covariant | ty::Bivariant => false, } } @@ -336,11 +330,7 @@ impl<'bccx, 'tcx> TypeRelation> for NllTypeRelating<'_, 'bccx, 'tcx debug!(?self.ambient_variance); // In a bivariant context this always succeeds. - let r = if self.ambient_variance == ty::Variance::Bivariant { - Ok(a) - } else { - self.relate(a, b) - }; + let r = if self.ambient_variance == ty::Bivariant { Ok(a) } else { self.relate(a, b) }; self.ambient_variance = old_ambient_variance; @@ -474,7 +464,7 @@ impl<'bccx, 'tcx> TypeRelation> for NllTypeRelating<'_, 'bccx, 'tcx } match self.ambient_variance { - ty::Variance::Covariant => { + ty::Covariant => { // Covariance, so we want `for<..> A <: for<..> B` -- // therefore we compare any instantiation of A (i.e., A // instantiated with existentials) against every @@ -489,7 +479,7 @@ impl<'bccx, 'tcx> TypeRelation> for NllTypeRelating<'_, 'bccx, 'tcx })?; } - ty::Variance::Contravariant => { + ty::Contravariant => { // Contravariance, so we want `for<..> A :> for<..> B` -- // therefore we compare every instantiation of A (i.e., A // instantiated with universals) against any @@ -504,7 +494,7 @@ impl<'bccx, 'tcx> TypeRelation> for NllTypeRelating<'_, 'bccx, 'tcx })?; } - ty::Variance::Invariant => { + ty::Invariant => { // Invariant, so we want `for<..> A == for<..> B` -- // therefore we want `exists<..> A == for<..> B` and // `exists<..> B == for<..> A`. @@ -525,7 +515,7 @@ impl<'bccx, 'tcx> TypeRelation> for NllTypeRelating<'_, 'bccx, 'tcx })?; } - ty::Variance::Bivariant => {} + ty::Bivariant => {} } Ok(a) @@ -584,23 +574,23 @@ impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx, fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { - ty::Variance::Covariant => ty::PredicateKind::AliasRelate( + ty::Covariant => ty::PredicateKind::AliasRelate( a.into(), b.into(), ty::AliasRelationDirection::Subtype, ), // a :> b is b <: a - ty::Variance::Contravariant => ty::PredicateKind::AliasRelate( + ty::Contravariant => ty::PredicateKind::AliasRelate( b.into(), a.into(), ty::AliasRelationDirection::Subtype, ), - ty::Variance::Invariant => ty::PredicateKind::AliasRelate( + ty::Invariant => ty::PredicateKind::AliasRelate( a.into(), b.into(), ty::AliasRelationDirection::Equate, ), - ty::Variance::Bivariant => { + ty::Bivariant => { unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)") } })]); diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index a6eef9f5662ca..4d0f35618ef27 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -112,25 +112,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Shift ops can have an RHS with a different numeric type. if matches!(bin_op, Shl | ShlUnchecked | Shr | ShrUnchecked) { - let size = left.layout.size.bits(); + let l_bits = left.layout.size.bits(); // Compute the equivalent shift modulo `size` that is in the range `0..size`. (This is // the one MIR operator that does *not* directly map to a single LLVM operation.) let (shift_amount, overflow) = if right.layout.abi.is_signed() { let shift_amount = r_signed(); - let overflow = shift_amount < 0 || shift_amount >= i128::from(size); - // Deliberately wrapping `as` casts: shift_amount *can* be negative, but the result - // of the `as` will be equal modulo `size` (since it is a power of two). - let masked_amount = (shift_amount as u128) % u128::from(size); - assert_eq!(overflow, shift_amount != i128::try_from(masked_amount).unwrap()); - (masked_amount, overflow) + let rem = shift_amount.rem_euclid(l_bits.into()); + // `rem` is guaranteed positive, so the `unwrap` cannot fail + (u128::try_from(rem).unwrap(), rem != shift_amount) } else { let shift_amount = r_unsigned(); - let overflow = shift_amount >= u128::from(size); - let masked_amount = shift_amount % u128::from(size); - assert_eq!(overflow, shift_amount != masked_amount); - (masked_amount, overflow) + let rem = shift_amount.rem_euclid(l_bits.into()); + (rem, rem != shift_amount) }; - let shift_amount = u32::try_from(shift_amount).unwrap(); // we masked so this will always fit + let shift_amount = u32::try_from(shift_amount).unwrap(); // we brought this in the range `0..size` so this will always fit // Compute the shifted result. let result = if left.layout.abi.is_signed() { let l = l_signed(); diff --git a/compiler/rustc_data_structures/src/flock.rs b/compiler/rustc_data_structures/src/flock.rs index 008565e4c7b97..e03962a54ecab 100644 --- a/compiler/rustc_data_structures/src/flock.rs +++ b/compiler/rustc_data_structures/src/flock.rs @@ -9,6 +9,10 @@ cfg_match! { mod linux; use linux as imp; } + cfg(target_os = "redox") => { + mod linux; + use linux as imp; + } cfg(unix) => { mod unix; use unix as imp; diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 445255e933d2d..914bd03675a7d 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -31,7 +31,7 @@ impl MutVisitor for Marker { // it's some advanced case with macro-generated macros. So if we cache the marked version // of that context once, we'll typically have a 100% cache hit rate after that. let Marker(expn_id, transparency, ref mut cache) = *self; - span.update_ctxt(|ctxt| { + *span = span.map_ctxt(|ctxt| { *cache .entry(ctxt) .or_insert_with(|| ctxt.apply_mark(expn_id.to_expn_id(), transparency)) diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 5e9c3c64e39ed..fc7a22833ff05 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -212,16 +212,16 @@ impl<'a, 'tcx> At<'a, 'tcx> { T: ToTrace<'tcx>, { match variance { - ty::Variance::Covariant => self.sub(define_opaque_types, expected, actual), - ty::Variance::Invariant => self.eq(define_opaque_types, expected, actual), - ty::Variance::Contravariant => self.sup(define_opaque_types, expected, actual), + ty::Covariant => self.sub(define_opaque_types, expected, actual), + ty::Invariant => self.eq(define_opaque_types, expected, actual), + ty::Contravariant => self.sup(define_opaque_types, expected, actual), // We could make this make sense but it's not readily // exposed and I don't feel like dealing with it. Note // that bivariance in general does a bit more than just // *nothing*, it checks that the types are the same // "modulo variance" basically. - ty::Variance::Bivariant => panic!("Bivariant given to `relate()`"), + ty::Bivariant => panic!("Bivariant given to `relate()`"), } } diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 7114b888718b3..b8dd501a721b5 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -345,7 +345,7 @@ impl<'tcx> InferCtxt<'tcx> { .args .iter() .enumerate() - .filter(|(i, _)| variances[*i] == ty::Variance::Invariant) + .filter(|(i, _)| variances[*i] == ty::Invariant) .filter_map(|(_, arg)| match arg.unpack() { GenericArgKind::Lifetime(r) => Some(r), GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, @@ -441,7 +441,7 @@ where let variances = self.tcx.variances_of(*def_id); for (v, s) in std::iter::zip(variances, args.iter()) { - if *v != ty::Variance::Bivariant { + if *v != ty::Bivariant { s.visit_with(self); } } diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs index 488f435994d4d..c02ab98b2baeb 100644 --- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs +++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs @@ -102,9 +102,7 @@ where }; for (idx, s) in args.iter().enumerate() { - if variances.map(|variances| variances[idx]) - != Some(ty::Variance::Bivariant) - { + if variances.map(|variances| variances[idx]) != Some(ty::Bivariant) { s.visit_with(self); } } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 87a2f0b45803d..d6e57d8538772 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -83,16 +83,16 @@ impl<'tcx> InferCtxt<'tcx> { // mention `?0`. if self.next_trait_solver() { let (lhs, rhs, direction) = match instantiation_variance { - ty::Variance::Invariant => { + ty::Invariant => { (generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate) } - ty::Variance::Covariant => { + ty::Covariant => { (generalized_ty.into(), source_ty.into(), AliasRelationDirection::Subtype) } - ty::Variance::Contravariant => { + ty::Contravariant => { (source_ty.into(), generalized_ty.into(), AliasRelationDirection::Subtype) } - ty::Variance::Bivariant => unreachable!("bivariant generalization"), + ty::Bivariant => unreachable!("bivariant generalization"), }; relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]); @@ -192,7 +192,7 @@ impl<'tcx> InferCtxt<'tcx> { relation.span(), relation.structurally_relate_aliases(), target_vid, - ty::Variance::Invariant, + ty::Invariant, source_ct, )?; @@ -210,14 +210,14 @@ impl<'tcx> InferCtxt<'tcx> { // generalized const and the source. if target_is_expected { relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, ty::VarianceDiagInfo::default(), generalized_ct, source_ct, )?; } else { relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, ty::VarianceDiagInfo::default(), source_ct, generalized_ct, @@ -411,7 +411,7 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { a_arg: ty::GenericArgsRef<'tcx>, b_arg: ty::GenericArgsRef<'tcx>, ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { - if self.ambient_variance == ty::Variance::Invariant { + if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). @@ -667,7 +667,7 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { // structural. ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => { let args = self.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, ty::VarianceDiagInfo::default(), args, args, diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs index cc17e60a79b00..067004ecaebbf 100644 --- a/compiler/rustc_infer/src/infer/relate/glb.rs +++ b/compiler/rustc_infer/src/infer/relate/glb.rs @@ -94,12 +94,7 @@ impl<'tcx> TypeRelation> for Glb<'_, '_, 'tcx> { // When higher-ranked types are involved, computing the GLB is // very challenging, switch to invariance. This is obviously // overly conservative but works ok in practice. - self.relate_with_variance( - ty::Variance::Invariant, - ty::VarianceDiagInfo::default(), - a, - b, - )?; + self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?; Ok(a) } else { Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?)) diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs index e9d300d349c62..2184416b4ccef 100644 --- a/compiler/rustc_infer/src/infer/relate/lub.rs +++ b/compiler/rustc_infer/src/infer/relate/lub.rs @@ -94,12 +94,7 @@ impl<'tcx> TypeRelation> for Lub<'_, '_, 'tcx> { // When higher-ranked types are involved, computing the LUB is // very challenging, switch to invariance. This is obviously // overly conservative but works ok in practice. - self.relate_with_variance( - ty::Variance::Invariant, - ty::VarianceDiagInfo::default(), - a, - b, - )?; + self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?; Ok(a) } else { Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?)) diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs index f7b2f11e3d707..f2bec9392d542 100644 --- a/compiler/rustc_infer/src/infer/relate/type_relating.rs +++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs @@ -42,7 +42,7 @@ impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> { a_arg: ty::GenericArgsRef<'tcx>, b_arg: ty::GenericArgsRef<'tcx>, ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { - if self.ambient_variance == ty::Variance::Invariant { + if self.ambient_variance == ty::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). @@ -325,23 +325,23 @@ impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> { fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) { self.register_predicates([ty::Binder::dummy(match self.ambient_variance { - ty::Variance::Covariant => ty::PredicateKind::AliasRelate( + ty::Covariant => ty::PredicateKind::AliasRelate( a.into(), b.into(), ty::AliasRelationDirection::Subtype, ), // a :> b is b <: a - ty::Variance::Contravariant => ty::PredicateKind::AliasRelate( + ty::Contravariant => ty::PredicateKind::AliasRelate( b.into(), a.into(), ty::AliasRelationDirection::Subtype, ), - ty::Variance::Invariant => ty::PredicateKind::AliasRelate( + ty::Invariant => ty::PredicateKind::AliasRelate( a.into(), b.into(), ty::AliasRelationDirection::Equate, ), - ty::Variance::Bivariant => { + ty::Bivariant => { unreachable!("Expected bivariance to be handled in relate_with_variance") } })]); diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 733c73bc3d078..043042a492b54 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -550,6 +550,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho .bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration .const_anon = use a const-anon item to suppress this lint + .macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed lint_non_local_definitions_impl_move_help = move the `impl` block outside of this {$body_kind_descr} {$depth -> diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index b377da31a581b..8059f5c1a2ea7 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1362,6 +1362,7 @@ pub enum NonLocalDefinitionsDiag { has_trait: bool, self_ty_str: String, of_trait_str: Option, + macro_to_change: Option<(String, &'static str)>, }, MacroRules { depth: u32, @@ -1387,6 +1388,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { has_trait, self_ty_str, of_trait_str, + macro_to_change, } => { diag.primary_message(fluent::lint_non_local_definitions_impl); diag.arg("depth", depth); @@ -1397,6 +1399,15 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { diag.arg("of_trait_str", of_trait_str); } + if let Some((macro_to_change, macro_kind)) = macro_to_change { + diag.arg("macro_to_change", macro_to_change); + diag.arg("macro_kind", macro_kind); + diag.note(fluent::lint_macro_to_change); + } + if let Some(cargo_update) = cargo_update { + diag.subdiagnostic(&diag.dcx, cargo_update); + } + if has_trait { diag.note(fluent::lint_bounds); diag.note(fluent::lint_with_trait); @@ -1422,9 +1433,6 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag { ); } - if let Some(cargo_update) = cargo_update { - diag.subdiagnostic(&diag.dcx, cargo_update); - } if let Some(const_anon) = const_anon { diag.note(fluent::lint_exception); if let Some(const_anon) = const_anon { diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index d7ffc34d824fd..b0ec6e06658f3 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -258,6 +258,13 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { Some((cx.tcx.def_span(parent), may_move)) }; + let macro_to_change = + if let ExpnKind::Macro(kind, name) = item.span.ctxt().outer_expn_data().kind { + Some((name.to_string(), kind.descr())) + } else { + None + }; + cx.emit_span_lint( NON_LOCAL_DEFINITIONS, ms, @@ -274,6 +281,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { move_to, may_remove, has_trait: impl_.of_trait.is_some(), + macro_to_change, }, ) } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index ebe77a1abfd8b..3edc5fe36cd2f 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1490,7 +1490,8 @@ pub enum BinOp { BitOr, /// The `<<` operator (shift left) /// - /// The offset is (uniquely) determined as follows: + /// The offset is given by `RHS.rem_euclid(LHS::BITS)`. + /// In other words, it is (uniquely) determined as follows: /// - it is "equal modulo LHS::BITS" to the RHS /// - it is in the range `0..LHS::BITS` Shl, @@ -1498,7 +1499,8 @@ pub enum BinOp { ShlUnchecked, /// The `>>` operator (shift right) /// - /// The offset is (uniquely) determined as follows: + /// The offset is given by `RHS.rem_euclid(LHS::BITS)`. + /// In other words, it is (uniquely) determined as follows: /// - it is "equal modulo LHS::BITS" to the RHS /// - it is in the range `0..LHS::BITS` /// diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c322c87bce4ad..5a94a53e175ea 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -16,7 +16,6 @@ pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeV pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; -pub use self::Variance::*; use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; use crate::metadata::ModChild; use crate::middle::privacy::EffectiveVisibilities; diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 4ae475d35d14d..8c323188826b2 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -142,7 +142,7 @@ impl<'tcx> Value> for &[ty::Variance] { && let Some(def_id) = frame.query.def_id { let n = tcx.generics_of(def_id).own_params.len(); - vec![ty::Variance::Bivariant; n].leak() + vec![ty::Bivariant; n].leak() } else { span_bug!( cycle_error.usage.as_ref().unwrap().0, diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 5413878936983..544f27b84e90d 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -699,7 +699,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // exactly `T` (i.e., with invariance). The variance field, in // contrast, is intended to be used to relate `T` to the type of // ``. - ty::Variance::Invariant, + ty::Invariant, ), }, ); diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 54eafdd828ae6..95cd703dbb3c0 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -92,7 +92,7 @@ impl<'tcx> Cx<'tcx> { kind: PatKind::AscribeUserType { ascription: Ascription { annotation, - variance: ty::Variance::Covariant, + variance: ty::Covariant, }, subpattern: pattern, }, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 158ca91fcf138..93db1f618533b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -525,7 +525,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { }; kind = PatKind::AscribeUserType { subpattern: Box::new(Pat { span, ty, kind }), - ascription: Ascription { annotation, variance: ty::Variance::Covariant }, + ascription: Ascription { annotation, variance: ty::Covariant }, }; } @@ -612,7 +612,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { annotation, // Note that use `Contravariant` here. See the // `variance` field documentation for details. - variance: ty::Variance::Contravariant, + variance: ty::Contravariant, }, }, ty: const_.ty(), diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index fe2237dd2e97a..2cbe0a01e9ece 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -225,13 +225,8 @@ impl<'tcx> Inliner<'tcx> { // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. let output_type = callee_body.return_ty(); - if !util::relate_types( - self.tcx, - self.param_env, - ty::Variance::Covariant, - output_type, - destination_ty, - ) { + if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty) + { trace!(?output_type, ?destination_ty); return Err("failed to normalize return type"); } @@ -261,13 +256,8 @@ impl<'tcx> Inliner<'tcx> { self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; - if !util::relate_types( - self.tcx, - self.param_env, - ty::Variance::Covariant, - input_type, - arg_ty, - ) { + if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty) + { trace!(?arg_ty, ?input_type); return Err("failed to normalize tuple argument type"); } @@ -276,13 +266,8 @@ impl<'tcx> Inliner<'tcx> { for (arg, input) in args.iter().zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx); - if !util::relate_types( - self.tcx, - self.param_env, - ty::Variance::Covariant, - input_type, - arg_ty, - ) { + if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty) + { trace!(?arg_ty, ?input_type); return Err("failed to normalize argument type"); } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 73bc87dc9abf9..e3cd7187e7731 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -866,10 +866,10 @@ impl<'tcx> Stable<'tcx> for ty::Variance { type T = stable_mir::mir::Variance; fn stable(&self, _: &mut Tables<'_>) -> Self::T { match self { - ty::Variance::Bivariant => stable_mir::mir::Variance::Bivariant, - ty::Variance::Contravariant => stable_mir::mir::Variance::Contravariant, - ty::Variance::Covariant => stable_mir::mir::Variance::Covariant, - ty::Variance::Invariant => stable_mir::mir::Variance::Invariant, + ty::Bivariant => stable_mir::mir::Variance::Bivariant, + ty::Contravariant => stable_mir::mir::Variance::Contravariant, + ty::Covariant => stable_mir::mir::Variance::Covariant, + ty::Invariant => stable_mir::mir::Variance::Invariant, } } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 99fcaf917fe9c..b7ffe6c618af7 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -520,6 +520,7 @@ impl SpanData { pub fn with_hi(&self, hi: BytePos) -> Span { Span::new(self.lo, hi, self.ctxt, self.parent) } + /// Avoid if possible, `Span::map_ctxt` should be preferred. #[inline] fn with_ctxt(&self, ctxt: SyntaxContext) -> Span { Span::new(self.lo, self.hi, ctxt, self.parent) @@ -576,9 +577,8 @@ impl Span { self.data().with_hi(hi) } #[inline] - pub fn with_ctxt(mut self, ctxt: SyntaxContext) -> Span { - self.update_ctxt(|_| ctxt); - self + pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span { + self.map_ctxt(|_| ctxt) } #[inline] pub fn parent(self) -> Option { @@ -1059,9 +1059,8 @@ impl Span { } #[inline] - pub fn apply_mark(mut self, expn_id: ExpnId, transparency: Transparency) -> Span { - self.update_ctxt(|ctxt| ctxt.apply_mark(expn_id, transparency)); - self + pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span { + self.map_ctxt(|ctxt| ctxt.apply_mark(expn_id, transparency)) } #[inline] @@ -1109,15 +1108,13 @@ impl Span { } #[inline] - pub fn normalize_to_macros_2_0(mut self) -> Span { - self.update_ctxt(|ctxt| ctxt.normalize_to_macros_2_0()); - self + pub fn normalize_to_macros_2_0(self) -> Span { + self.map_ctxt(|ctxt| ctxt.normalize_to_macros_2_0()) } #[inline] - pub fn normalize_to_macro_rules(mut self) -> Span { - self.update_ctxt(|ctxt| ctxt.normalize_to_macro_rules()); - self + pub fn normalize_to_macro_rules(self) -> Span { + self.map_ctxt(|ctxt| ctxt.normalize_to_macro_rules()) } } diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 52a1267f8918c..9d5bc5b05125e 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -87,43 +87,150 @@ pub struct Span { ctxt_or_parent_or_marker: u16, } -impl Span { +// Convenience structures for all span formats. +#[derive(Clone, Copy)] +struct InlineCtxt { + lo: u32, + len: u16, + ctxt: u16, +} + +#[derive(Clone, Copy)] +struct InlineParent { + lo: u32, + len_with_tag: u16, + parent: u16, +} + +#[derive(Clone, Copy)] +struct PartiallyInterned { + index: u32, + ctxt: u16, +} + +#[derive(Clone, Copy)] +struct Interned { + index: u32, +} + +impl InlineCtxt { #[inline] - fn data_inline_ctxt(self) -> SpanData { - let len = self.len_with_tag_or_marker as u32; + fn data(self) -> SpanData { + let len = self.len as u32; debug_assert!(len <= MAX_LEN); SpanData { - lo: BytePos(self.lo_or_index), - hi: BytePos(self.lo_or_index.debug_strict_add(len)), - ctxt: SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32), + lo: BytePos(self.lo), + hi: BytePos(self.lo.debug_strict_add(len)), + ctxt: SyntaxContext::from_u32(self.ctxt as u32), parent: None, } } #[inline] - fn data_inline_parent(self) -> SpanData { - let len = (self.len_with_tag_or_marker & !PARENT_TAG) as u32; + fn span(lo: u32, len: u16, ctxt: u16) -> Span { + Span { lo_or_index: lo, len_with_tag_or_marker: len, ctxt_or_parent_or_marker: ctxt } + } + #[inline] + fn from_span(span: Span) -> InlineCtxt { + let (lo, len, ctxt) = + (span.lo_or_index, span.len_with_tag_or_marker, span.ctxt_or_parent_or_marker); + InlineCtxt { lo, len, ctxt } + } +} + +impl InlineParent { + #[inline] + fn data(self) -> SpanData { + let len = (self.len_with_tag & !PARENT_TAG) as u32; debug_assert!(len <= MAX_LEN); - let parent = LocalDefId { - local_def_index: DefIndex::from_u32(self.ctxt_or_parent_or_marker as u32), - }; SpanData { - lo: BytePos(self.lo_or_index), - hi: BytePos(self.lo_or_index.debug_strict_add(len)), + lo: BytePos(self.lo), + hi: BytePos(self.lo.debug_strict_add(len)), ctxt: SyntaxContext::root(), - parent: Some(parent), + parent: Some(LocalDefId { local_def_index: DefIndex::from_u32(self.parent as u32) }), } } #[inline] - fn data_partially_interned(self) -> SpanData { + fn span(lo: u32, len: u16, parent: u16) -> Span { + let (lo_or_index, len_with_tag_or_marker, ctxt_or_parent_or_marker) = + (lo, PARENT_TAG | len, parent); + Span { lo_or_index, len_with_tag_or_marker, ctxt_or_parent_or_marker } + } + #[inline] + fn from_span(span: Span) -> InlineParent { + let (lo, len_with_tag, parent) = + (span.lo_or_index, span.len_with_tag_or_marker, span.ctxt_or_parent_or_marker); + InlineParent { lo, len_with_tag, parent } + } +} + +impl PartiallyInterned { + #[inline] + fn data(self) -> SpanData { SpanData { - ctxt: SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32), - ..with_span_interner(|interner| interner.spans[self.lo_or_index as usize]) + ctxt: SyntaxContext::from_u32(self.ctxt as u32), + ..with_span_interner(|interner| interner.spans[self.index as usize]) } } #[inline] - fn data_interned(self) -> SpanData { - with_span_interner(|interner| interner.spans[self.lo_or_index as usize]) + fn span(index: u32, ctxt: u16) -> Span { + let (lo_or_index, len_with_tag_or_marker, ctxt_or_parent_or_marker) = + (index, BASE_LEN_INTERNED_MARKER, ctxt); + Span { lo_or_index, len_with_tag_or_marker, ctxt_or_parent_or_marker } + } + #[inline] + fn from_span(span: Span) -> PartiallyInterned { + PartiallyInterned { index: span.lo_or_index, ctxt: span.ctxt_or_parent_or_marker } + } +} + +impl Interned { + #[inline] + fn data(self) -> SpanData { + with_span_interner(|interner| interner.spans[self.index as usize]) + } + #[inline] + fn span(index: u32) -> Span { + let (lo_or_index, len_with_tag_or_marker, ctxt_or_parent_or_marker) = + (index, BASE_LEN_INTERNED_MARKER, CTXT_INTERNED_MARKER); + Span { lo_or_index, len_with_tag_or_marker, ctxt_or_parent_or_marker } } + #[inline] + fn from_span(span: Span) -> Interned { + Interned { index: span.lo_or_index } + } +} + +// This code is very hot, and converting span to an enum and matching on it doesn't optimize away +// properly. So we are using a macro emulating such a match, but expand it directly to an if-else +// chain. +macro_rules! match_span_kind { + ( + $span:expr, + InlineCtxt($span1:ident) => $arm1:expr, + InlineParent($span2:ident) => $arm2:expr, + PartiallyInterned($span3:ident) => $arm3:expr, + Interned($span4:ident) => $arm4:expr, + ) => { + if $span.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { + if $span.len_with_tag_or_marker & PARENT_TAG == 0 { + // Inline-context format. + let $span1 = InlineCtxt::from_span($span); + $arm1 + } else { + // Inline-parent format. + let $span2 = InlineParent::from_span($span); + $arm2 + } + } else if $span.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { + // Partially-interned format. + let $span3 = PartiallyInterned::from_span($span); + $arm3 + } else { + // Interned format. + let $span4 = Interned::from_span($span); + $arm4 + } + }; } // `MAX_LEN` is chosen so that `PARENT_TAG | MAX_LEN` is distinct from @@ -154,23 +261,13 @@ impl Span { let (len, ctxt32) = (hi.0 - lo.0, ctxt.as_u32()); if len <= MAX_LEN { if ctxt32 <= MAX_CTXT && parent.is_none() { - // Inline-context format. - return Span { - lo_or_index: lo.0, - len_with_tag_or_marker: len as u16, - ctxt_or_parent_or_marker: ctxt32 as u16, - }; + return InlineCtxt::span(lo.0, len as u16, ctxt32 as u16); } else if ctxt32 == 0 && let Some(parent) = parent && let parent32 = parent.local_def_index.as_u32() && parent32 <= MAX_CTXT { - // Inline-parent format. - return Span { - lo_or_index: lo.0, - len_with_tag_or_marker: PARENT_TAG | len as u16, - ctxt_or_parent_or_marker: parent32 as u16, - }; + return InlineParent::span(lo.0, len as u16, parent32 as u16); } } @@ -179,20 +276,10 @@ impl Span { with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent })) }; if ctxt32 <= MAX_CTXT { - // Partially-interned format. - Span { - // Interned ctxt should never be read, so it can use any value. - lo_or_index: index(SyntaxContext::from_u32(u32::MAX)), - len_with_tag_or_marker: BASE_LEN_INTERNED_MARKER, - ctxt_or_parent_or_marker: ctxt32 as u16, - } + // Interned ctxt should never be read, so it can use any value. + PartiallyInterned::span(index(SyntaxContext::from_u32(u32::MAX)), ctxt32 as u16) } else { - // Interned format. - Span { - lo_or_index: index(ctxt), - len_with_tag_or_marker: BASE_LEN_INTERNED_MARKER, - ctxt_or_parent_or_marker: CTXT_INTERNED_MARKER, - } + Interned::span(index(ctxt)) } } @@ -209,20 +296,12 @@ impl Span { /// This function must not be used outside the incremental engine. #[inline] pub fn data_untracked(self) -> SpanData { - if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { - if self.len_with_tag_or_marker & PARENT_TAG == 0 { - // Inline-context format. - self.data_inline_ctxt() - } else { - // Inline-parent format. - self.data_inline_parent() - } - } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { - // Partially-interned format. - self.data_partially_interned() - } else { - // Interned format. - self.data_interned() + match_span_kind! { + self, + InlineCtxt(span) => span.data(), + InlineParent(span) => span.data(), + PartiallyInterned(span) => span.data(), + Interned(span) => span.data(), } } @@ -247,68 +326,57 @@ impl Span { // update doesn't change format. All non-inline or format changing scenarios require accessing // interner and can fall back to `Span::new`. #[inline] - pub fn update_ctxt(&mut self, update: impl FnOnce(SyntaxContext) -> SyntaxContext) { + pub fn map_ctxt(self, update: impl FnOnce(SyntaxContext) -> SyntaxContext) -> Span { let (updated_ctxt32, data); - if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { - if self.len_with_tag_or_marker & PARENT_TAG == 0 { - // Inline-context format. + match_span_kind! { + self, + InlineCtxt(span) => { updated_ctxt32 = - update(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)).as_u32(); + update(SyntaxContext::from_u32(span.ctxt as u32)).as_u32(); // Any small new context including zero will preserve the format. if updated_ctxt32 <= MAX_CTXT { - self.ctxt_or_parent_or_marker = updated_ctxt32 as u16; - return; + return InlineCtxt::span(span.lo, span.len, updated_ctxt32 as u16); } - data = self.data_inline_ctxt(); - } else { - // Inline-parent format. + data = span.data(); + }, + InlineParent(span) => { updated_ctxt32 = update(SyntaxContext::root()).as_u32(); // Only if the new context is zero the format will be preserved. if updated_ctxt32 == 0 { // Do nothing. - return; + return self; } - data = self.data_inline_parent(); - } - } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { - // Partially-interned format. - updated_ctxt32 = - update(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)).as_u32(); - // Any small new context excluding zero will preserve the format. - // Zero may change the format to `InlineParent` if parent and len are small enough. - if updated_ctxt32 <= MAX_CTXT && updated_ctxt32 != 0 { - self.ctxt_or_parent_or_marker = updated_ctxt32 as u16; - return; - } - data = self.data_partially_interned(); - } else { - // Interned format. - data = self.data_interned(); - updated_ctxt32 = update(data.ctxt).as_u32(); + data = span.data(); + }, + PartiallyInterned(span) => { + updated_ctxt32 = update(SyntaxContext::from_u32(span.ctxt as u32)).as_u32(); + // Any small new context excluding zero will preserve the format. + // Zero may change the format to `InlineParent` if parent and len are small enough. + if updated_ctxt32 <= MAX_CTXT && updated_ctxt32 != 0 { + return PartiallyInterned::span(span.index, updated_ctxt32 as u16); + } + data = span.data(); + }, + Interned(span) => { + data = span.data(); + updated_ctxt32 = update(data.ctxt).as_u32(); + }, } // We could not keep the span in the same inline format, fall back to the complete logic. - *self = data.with_ctxt(SyntaxContext::from_u32(updated_ctxt32)); + data.with_ctxt(SyntaxContext::from_u32(updated_ctxt32)) } // Returns either syntactic context, if it can be retrieved without taking the interner lock, // or an index into the interner if it cannot. #[inline] fn inline_ctxt(self) -> Result { - if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { - if self.len_with_tag_or_marker & PARENT_TAG == 0 { - // Inline-context format. - Ok(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)) - } else { - // Inline-parent format. - Ok(SyntaxContext::root()) - } - } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { - // Partially-interned format. - Ok(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)) - } else { - // Interned format. - Err(self.lo_or_index as usize) + match_span_kind! { + self, + InlineCtxt(span) => Ok(SyntaxContext::from_u32(span.ctxt as u32)), + InlineParent(_span) => Ok(SyntaxContext::root()), + PartiallyInterned(span) => Ok(SyntaxContext::from_u32(span.ctxt as u32)), + Interned(span) => Err(span.index as usize), } } diff --git a/compiler/rustc_target/src/spec/base/redox.rs b/compiler/rustc_target/src/spec/base/redox.rs index 468fe478549b2..9070791e9dfc4 100644 --- a/compiler/rustc_target/src/spec/base/redox.rs +++ b/compiler/rustc_target/src/spec/base/redox.rs @@ -1,4 +1,4 @@ -use crate::spec::{cvs, RelroLevel, TargetOptions}; +use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { TargetOptions { @@ -12,6 +12,8 @@ pub fn opts() -> TargetOptions { has_thread_local: true, crt_static_default: true, crt_static_respected: true, + crt_static_allows_dylibs: true, + late_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lgcc"]), ..Default::default() } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index adea2caabbe75..42860b1059ed7 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1647,6 +1647,7 @@ supported_targets! { ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), ("aarch64-unknown-redox", aarch64_unknown_redox), + ("i686-unknown-redox", i686_unknown_redox), ("x86_64-unknown-redox", x86_64_unknown_redox), ("i386-apple-ios", i386_apple_ios), diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs new file mode 100644 index 0000000000000..83252fadb78ea --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs @@ -0,0 +1,27 @@ +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; + +pub fn target() -> Target { + let mut base = base::redox::opts(); + base.cpu = "pentiumpro".into(); + base.plt_by_default = false; + base.max_atomic_width = Some(64); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved + base.stack_probes = StackProbeType::Call; + + Target { + llvm_target: "i686-unknown-redox".into(), + metadata: crate::spec::TargetMetadata { + description: None, + tier: None, + host_tools: None, + std: None, + }, + pointer_width: 32, + data_layout: + "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128" + .into(), + arch: "x86".into(), + options: base, + } +} diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index 59a8de99b8f6d..4e52caa5a5b8e 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -61,8 +61,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { trace!(?lhs, ?rhs); let variance = match direction { - ty::AliasRelationDirection::Equate => ty::Variance::Invariant, - ty::AliasRelationDirection::Subtype => ty::Variance::Covariant, + ty::AliasRelationDirection::Equate => ty::Invariant, + ty::AliasRelationDirection::Subtype => ty::Covariant, }; match (lhs.to_alias_term(), rhs.to_alias_term()) { (None, None) => { @@ -78,7 +78,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { self.relate_rigid_alias_non_alias( param_env, alias, - variance.xform(ty::Variance::Contravariant), + variance.xform(ty::Contravariant), lhs, )?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 50253d815283a..2f3beed1a335f 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -40,7 +40,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { Ok(res) => Ok(res), Err(NoSolution) => { let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; - self.relate_rigid_alias_non_alias(param_env, alias, ty::Variance::Invariant, term)?; + self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 7f0c3df381daf..4775a0f8cbbe4 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -74,6 +74,7 @@ pub use DynKind::*; pub use InferTy::*; pub use RegionKind::*; pub use TyKind::*; +pub use Variance::*; rustc_index::newtype_index! { /// A [De Bruijn index][dbi] is a standard means of representing diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index cae1d13020d34..8a6ba87b60e06 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -128,7 +128,7 @@ pub fn relate_args_invariantly>( b_arg: I::GenericArgs, ) -> RelateResult { relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| { - relation.relate_with_variance(ty::Variance::Invariant, VarianceDiagInfo::default(), a, b) + relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b) })) } @@ -145,7 +145,7 @@ pub fn relate_args_with_variances>( let mut cached_ty = None; let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| { let variance = variances[i]; - let variance_info = if variance == ty::Variance::Invariant && fetch_ty_for_diag { + let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { let ty = *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg)); VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } @@ -191,7 +191,7 @@ impl Relate for ty::FnSig { relation.relate(a, b) } else { relation.relate_with_variance( - ty::Variance::Contravariant, + ty::Contravariant, VarianceDiagInfo::default(), a, b, @@ -311,13 +311,13 @@ impl Relate for ty::ExistentialProjection { })) } else { let term = relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, VarianceDiagInfo::default(), a.term, b.term, )?; let args = relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, VarianceDiagInfo::default(), a.args, b.args, @@ -466,9 +466,9 @@ pub fn structurally_relate_tys>( } let (variance, info) = match a_mutbl { - Mutability::Not => (ty::Variance::Covariant, VarianceDiagInfo::None), + Mutability::Not => (ty::Covariant, VarianceDiagInfo::None), Mutability::Mut => { - (ty::Variance::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 }) + (ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 }) } }; @@ -483,9 +483,9 @@ pub fn structurally_relate_tys>( } let (variance, info) = match a_mutbl { - Mutability::Not => (ty::Variance::Covariant, VarianceDiagInfo::None), + Mutability::Not => (ty::Covariant, VarianceDiagInfo::None), Mutability::Mut => { - (ty::Variance::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 }) + (ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 }) } }; @@ -612,7 +612,7 @@ pub fn structurally_relate_consts>( } let args = relation.relate_with_variance( - ty::Variance::Invariant, + ty::Invariant, VarianceDiagInfo::default(), au.args, bu.args, diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 6da410ed2f279..706f2c5bf0701 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -138,6 +138,25 @@ def build_args(self, configure_args=None, args=None, env=None): if env is None: env = {} + # This test ends up invoking build_bootstrap_cmd, which searches for + # the Cargo binary and errors out if it cannot be found. This is not a + # problem in most cases, but there is a scenario where it would cause + # the test to fail. + # + # When a custom local Cargo is configured in config.toml (with the + # build.cargo setting), no Cargo is downloaded to any location known by + # bootstrap, and bootstrap relies on that setting to find it. + # + # In this test though we are not using the config.toml of the caller: + # we are generating a blank one instead. If we don't set build.cargo in + # it, the test will have no way to find Cargo, failing the test. + cargo_bin = os.environ.get("BOOTSTRAP_TEST_CARGO_BIN") + if cargo_bin is not None: + configure_args += ["--set", "build.cargo=" + cargo_bin] + rustc_bin = os.environ.get("BOOTSTRAP_TEST_RUSTC_BIN") + if rustc_bin is not None: + configure_args += ["--set", "build.rustc=" + rustc_bin] + env = env.copy() env["PATH"] = os.environ["PATH"] diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 7556a19c90ca0..e08fc3bb1ec63 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -3040,6 +3040,8 @@ impl Step for Bootstrap { .args(["-m", "unittest", "bootstrap_test.py"]) .env("BUILD_DIR", &builder.out) .env("BUILD_PLATFORM", builder.build.build.triple) + .env("BOOTSTRAP_TEST_RUSTC_BIN", &builder.initial_rustc) + .env("BOOTSTRAP_TEST_CARGO_BIN", &builder.initial_cargo) .current_dir(builder.src.join("src/bootstrap/")); // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible. // Use `python -m unittest` manually if you want to pass arguments. diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 6cf31f2e61e1c..e0a9674ae5a90 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -823,19 +823,29 @@ impl Step for LibcxxVersionTool { fn run(self, builder: &Builder<'_>) -> LibcxxVersion { let out_dir = builder.out.join(self.target.to_string()).join("libcxx-version"); - let _ = fs::remove_dir_all(&out_dir); - t!(fs::create_dir_all(&out_dir)); + let executable = out_dir.join(exe("libcxx-version", self.target)); - let compiler = builder.cxx(self.target).unwrap(); - let mut cmd = Command::new(compiler); + // This is a sanity-check specific step, which means it is frequently called (when using + // CI LLVM), and compiling `src/tools/libcxx-version/main.cpp` at the beginning of the bootstrap + // invocation adds a fair amount of overhead to the process (see https://github.com/rust-lang/rust/issues/126423). + // Therefore, we want to avoid recompiling this file unnecessarily. + if !executable.exists() { + if !out_dir.exists() { + t!(fs::create_dir_all(&out_dir)); + } - let executable = out_dir.join(exe("libcxx-version", self.target)); - cmd.arg("-o").arg(&executable).arg(builder.src.join("src/tools/libcxx-version/main.cpp")); + let compiler = builder.cxx(self.target).unwrap(); + let mut cmd = Command::new(compiler); - builder.run_cmd(&mut cmd); + cmd.arg("-o") + .arg(&executable) + .arg(builder.src.join("src/tools/libcxx-version/main.cpp")); - if !executable.exists() { - panic!("Something went wrong. {} is not present", executable.display()); + builder.run_cmd(&mut cmd); + + if !executable.exists() { + panic!("Something went wrong. {} is not present", executable.display()); + } } let version_output = output(&mut Command::new(executable)); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 36b44d0169c9c..6664c5b451c87 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1189,7 +1189,19 @@ impl Config { pub fn parse(args: &[String]) -> Config { #[cfg(test)] fn get_toml(_: &Path) -> TomlConfig { - TomlConfig::default() + let mut default = TomlConfig::default(); + + // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the + // same ones used to call the tests. If we don't do that, bootstrap will use its own + // detection logic to find a suitable rustc and Cargo, which doesn't work when the + // caller is specìfying a custom local rustc or Cargo in their config.toml. + default.build = Some(Build { + rustc: std::env::var_os("RUSTC").map(|v| v.into()), + cargo: std::env::var_os("CARGO").map(|v| v.into()), + ..Build::default() + }); + + default } #[cfg(not(test))] diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index da80f10b7dddd..ffa2e64506044 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -40,6 +40,7 @@ pub struct Finder { #[cfg(not(feature = "bootstrap-self-test"))] const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "i686-unknown-redox", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM @@ -128,6 +129,9 @@ pub fn check(build: &mut Build) { eprintln!( "Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option." ); + eprintln!( + "If you choose to upgrade libstdc++, run `x clean` or delete `build/host/libcxx-version` manually after the upgrade." + ); } } tool::LibcxxVersion::Llvm(_) => { diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile index 1704bef1e4ed0..414bcc52484c9 100644 --- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile @@ -6,8 +6,12 @@ FROM centos:7 WORKDIR /build +# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault. +RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \ + -e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!' +RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf + RUN yum upgrade -y && \ - yum install -y epel-release && \ yum install -y \ automake \ bzip2 \ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 4e1aae9822135..4aa1a3ccc2a5d 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -6,8 +6,12 @@ FROM centos:7 WORKDIR /build +# CentOS 7 EOL is June 30, 2024, but the repos remain in the vault. +RUN sed -i /etc/yum.repos.d/*.repo -e 's!^mirrorlist!#mirrorlist!' \ + -e 's!^#baseurl=http://mirror.centos.org/!baseurl=https://vault.centos.org/!' +RUN sed -i 's/enabled=1/enabled=0/' /etc/yum/pluginconf.d/fastestmirror.conf + RUN yum upgrade -y && \ - yum install -y epel-release && \ yum install -y \ automake \ bzip2 \ diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 201ace5ce3a7b..e76ebb8f8aa8c 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -71,6 +71,7 @@ - [*-unknown-hermit](platform-support/hermit.md) - [\*-unknown-netbsd\*](platform-support/netbsd.md) - [*-unknown-openbsd](platform-support/openbsd.md) + - [*-unknown-redox](platform-support/redox.md) - [\*-unknown-uefi](platform-support/unknown-uefi.md) - [wasm32-wasip1](platform-support/wasm32-wasip1.md) - [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index e55bb3bd155b7..834e909c0654a 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -203,7 +203,7 @@ target | std | notes `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) [`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat -`x86_64-unknown-redox` | ✓ | Redox OS +[`x86_64-unknown-redox`](platform-support/redox.md) | ✓ | Redox OS [`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 64-bit UEFI [^x86_32-floats-x87]: Floating-point support on `i586` targets is non-compliant: the `x87` registers and instructions used for these targets do not provide IEEE-754-compliant behavior, in particular when it comes to rounding and NaN payload bits. See [issue #114479][x86-32-float-issue]. @@ -258,7 +258,7 @@ target | std | host | notes `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD -`aarch64-unknown-redox` | ? | | ARM64 Redox OS +[`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS `aarch64-uwp-windows-msvc` | ✓ | | `aarch64-wrs-vxworks` | ? | | `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) @@ -300,6 +300,7 @@ target | std | host | notes [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI] [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI] +[`i686-unknown-redox`](platform-support/redox.md) | ✓ | | i686 Redox OS `i686-uwp-windows-gnu` | ✓ | | [^x86_32-floats-return-ABI] `i686-uwp-windows-msvc` | ✓ | | [^x86_32-floats-return-ABI] [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] diff --git a/src/doc/rustc/src/platform-support/redox.md b/src/doc/rustc/src/platform-support/redox.md new file mode 100644 index 0000000000000..1b3321956ef7b --- /dev/null +++ b/src/doc/rustc/src/platform-support/redox.md @@ -0,0 +1,53 @@ +# `*-unknown-redox` + +**Tier: 2/3** + +Targets for the [Redox OS](https://redox-os.org/) operating +system. + +Target triplets available so far: + +- `x86_64-unknown-redox` (tier 2) +- `aarch64-unknown-redox` (tier 3) +- `i686-unknown-redox` (tier 3) + +## Target maintainers + +- Jeremy Soller ([@jackpot51](https://github.com/jackpot51)) + +## Requirements + +These targets are natively compiled and can be cross-compiled. Std is fully supported. + +The targets are only expected to work with the latest version of Redox OS as the ABI is not yet stable. + +`extern "C"` uses the official calling convention of the respective architectures. + +Redox OS binaries use ELF as file format. + +## Building the target + +You can build Rust with support for the targets by adding it to the `target` list in `config.toml`. In addition a copy of [relibc] needs to be present in the linker search path. + +```toml +[build] +build-stage = 1 +target = [ + "", + "x86_64-unknown-redox", + "aarch64-unknown-redox", + "i686-unknown-redox", +] +``` + +[relibc]: https://gitlab.redox-os.org/redox-os/relibc + +## Building Rust programs and testing + +Rust does not yet ship pre-compiled artifacts for Redox OS except for x86_64-unknown-redox. + +The easiest way to build and test programs for Redox OS is using [redoxer](https://gitlab.redox-os.org/redox-os/redoxer) which sets up the required compiler toolchain for building as well as runs programs inside a Redox OS VM using QEMU. + +## Cross-compilation toolchains and C code + +The target supports C code. Pre-compiled C toolchains can be found at . diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index b4d47cba7c5bc..a709aab7ce220 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -103,6 +103,7 @@ static TARGETS: &[&str] = &[ "i686-unknown-freebsd", "i686-unknown-linux-gnu", "i686-unknown-linux-musl", + "i686-unknown-redox", "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", "loongarch64-unknown-none", diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 4c54fe639e3e6..b069e667bf5d5 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -228,6 +228,9 @@ //@ revisions: i686_unknown_openbsd //@ [i686_unknown_openbsd] compile-flags: --target i686-unknown-openbsd //@ [i686_unknown_openbsd] needs-llvm-components: x86 +//@ revisions: i686_unknown_redox +//@ [i686_unknown_redox] compile-flags: --target i686-unknown-redox +//@ [i686_unknown_redox] needs-llvm-components: x86 //@ revisions: i686_wrs_vxworks //@ [i686_wrs_vxworks] compile-flags: --target i686-wrs-vxworks //@ [i686_wrs_vxworks] needs-llvm-components: x86 diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index 888fd2e61837f..afd37d03a231c 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -8,9 +8,10 @@ LL | non_local_macro::non_local_impl!(LocalStruct); | `Debug` is not local | move the `impl` block outside of this constant `_IMPL_DEBUG` | + = note: the macro `non_local_macro::non_local_impl` defines the non-local `impl`, and may need to be changed + = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro` = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro` = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue = note: `#[warn(non_local_definitions)]` on by default diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr index b52301d1aa086..fa9ba2cb785d9 100644 --- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr +++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr @@ -12,6 +12,7 @@ LL | impl MacroTrait for OutsideStruct {} LL | m!(); | ---- in this macro invocation | + = note: the macro `m` defines the non-local `impl`, and may need to be changed = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue