diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast/src/token.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/feature_gate.rs | 34 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/graph/iterate/mod.rs | 15 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/active.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_feature/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/query.rs | 68 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/lints.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/avr_gnu_base.rs | 2 |
10 files changed, 54 insertions, 81 deletions
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index a2c651d1537..09c0983bb9d 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -173,6 +173,7 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool { kw::Move, kw::Return, kw::True, + kw::Try, kw::Unsafe, kw::While, kw::Yield, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 0ee8ef55e61..97e6b363eff 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -608,6 +608,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { pub fn check_crate(krate: &ast::Crate, sess: &Session) { maybe_stage_features(sess, krate); + check_incompatible_features(sess); let mut visitor = PostExpansionVisitor { sess, features: &sess.features_untracked() }; let spans = sess.parse_sess.gated_spans.spans.borrow(); @@ -677,3 +678,36 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) { } } } + +fn check_incompatible_features(sess: &Session) { + let features = sess.features_untracked(); + + let declared_features = features + .declared_lang_features + .iter() + .copied() + .map(|(name, span, _)| (name, span)) + .chain(features.declared_lib_features.iter().copied()); + + for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES + .iter() + .filter(|&&(f1, f2)| features.enabled(f1) && features.enabled(f2)) + { + if let Some((f1_name, f1_span)) = declared_features.clone().find(|(name, _)| name == f1) { + if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2) + { + let spans = vec![f1_span, f2_span]; + sess.struct_span_err( + spans.clone(), + &format!( + "features `{}` and `{}` are incompatible, using them at the same time \ + is not allowed", + f1_name, f2_name + ), + ) + .help("remove one of these features") + .emit(); + } + } + } +} diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 64ff6130ddf..bc3d1ce53ba 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -87,11 +87,8 @@ where } /// Allows searches to terminate early with a value. -#[derive(Clone, Copy, Debug)] -pub enum ControlFlow<T> { - Break(T), - Continue, -} +// FIXME (#75744): remove the alias once the generics are in a better order and `C=()`. +pub type ControlFlow<T> = std::ops::ControlFlow<(), T>; /// The status of a node in the depth-first search. /// @@ -260,12 +257,12 @@ where _node: G::Node, _prior_status: Option<NodeStatus>, ) -> ControlFlow<Self::BreakVal> { - ControlFlow::Continue + ControlFlow::CONTINUE } /// Called after all nodes reachable from this one have been examined. fn node_settled(&mut self, _node: G::Node) -> ControlFlow<Self::BreakVal> { - ControlFlow::Continue + ControlFlow::CONTINUE } /// Behave as if no edges exist from `source` to `target`. @@ -289,8 +286,8 @@ where prior_status: Option<NodeStatus>, ) -> ControlFlow<Self::BreakVal> { match prior_status { - Some(NodeStatus::Visited) => ControlFlow::Break(()), - _ => ControlFlow::Continue, + Some(NodeStatus::Visited) => ControlFlow::BREAK, + _ => ControlFlow::CONTINUE, } } } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index de4e7a13424..88c160e93b6 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -8,6 +8,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(incomplete_features)] +#![feature(control_flow_enum)] #![feature(in_band_lifetimes)] #![feature(unboxed_closures)] #![feature(generators)] diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index e858980738d..3d7b3da45cc 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -605,3 +605,8 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::lazy_normalization_consts, sym::specialization, ]; + +/// Some features are not allowed to be used together at the same time, if +/// the two are present, produce an error +pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = + &[(sym::const_generics, sym::min_const_generics)]; diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 4393368cd45..15564a59658 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -131,7 +131,7 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZeroU3 } pub use accepted::ACCEPTED_FEATURES; -pub use active::{Features, ACTIVE_FEATURES, INCOMPLETE_FEATURES}; +pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES, INCOMPLETE_FEATURES}; pub use builtin_attrs::{ deprecated_attributes, find_gated_cfg, is_builtin_attr_name, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP, diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index ffa6e6f5324..f9cadb3bb2d 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -190,74 +190,6 @@ impl<'tcx> FromIterator<DtorckConstraint<'tcx>> for DtorckConstraint<'tcx> { } } -/// This returns true if the type `ty` is "trivial" for -/// dropck-outlives -- that is, if it doesn't require any types to -/// outlive. This is similar but not *quite* the same as the -/// `needs_drop` test in the compiler already -- that is, for every -/// type T for which this function return true, needs-drop would -/// return `false`. But the reverse does not hold: in particular, -/// `needs_drop` returns false for `PhantomData`, but it is not -/// trivial for dropck-outlives. -/// -/// Note also that `needs_drop` requires a "global" type (i.e., one -/// with erased regions), but this function does not. -pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { - match ty.kind() { - // None of these types have a destructor and hence they do not - // require anything in particular to outlive the dtor's - // execution. - ty::Infer(ty::FreshIntTy(_)) - | ty::Infer(ty::FreshFloatTy(_)) - | ty::Bool - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Never - | ty::FnDef(..) - | ty::FnPtr(_) - | ty::Char - | ty::GeneratorWitness(..) - | ty::RawPtr(_) - | ty::Ref(..) - | ty::Str - | ty::Foreign(..) - | ty::Error(_) => true, - - // [T; N] and [T] have same properties as T. - ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty), - - // (T1..Tn) and closures have same properties as T1..Tn -- - // check if *any* of those are trivial. - ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())), - ty::Closure(_, ref substs) => { - substs.as_closure().upvar_tys().all(|t| trivial_dropck_outlives(tcx, t)) - } - - ty::Adt(def, _) => { - if Some(def.did) == tcx.lang_items().manually_drop() { - // `ManuallyDrop` never has a dtor. - true - } else { - // Other types might. Moreover, PhantomData doesn't - // have a dtor, but it is considered to own its - // content, so it is non-trivial. Unions can have `impl Drop`, - // and hence are non-trivial as well. - false - } - } - - // The following *might* require a destructor: needs deeper inspection. - ty::Dynamic(..) - | ty::Projection(..) - | ty::Param(_) - | ty::Opaque(..) - | ty::Placeholder(..) - | ty::Infer(_) - | ty::Bound(..) - | ty::Generator(..) => false, - } -} - #[derive(Debug, HashStable)] pub struct CandidateStep<'tcx> { pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 313bb979a51..e55180ff4be 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -6,6 +6,7 @@ #![feature(box_syntax)] #![feature(const_fn)] #![feature(const_panic)] +#![feature(control_flow_enum)] #![feature(crate_visibility_modifier)] #![feature(bool_to_option)] #![feature(or_patterns)] diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 22ce278cee0..a8d7c612a84 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -117,7 +117,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { // A diverging InlineAsm is treated as non-recursing TerminatorKind::InlineAsm { destination, .. } => { if destination.is_some() { - ControlFlow::Continue + ControlFlow::CONTINUE } else { ControlFlow::Break(NonRecursive) } @@ -131,7 +131,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } | TerminatorKind::Goto { .. } - | TerminatorKind::SwitchInt { .. } => ControlFlow::Continue, + | TerminatorKind::SwitchInt { .. } => ControlFlow::CONTINUE, } } @@ -144,7 +144,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { } } - ControlFlow::Continue + ControlFlow::CONTINUE } fn ignore_edge(&mut self, bb: BasicBlock, target: BasicBlock) -> bool { diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index ff559c2bfd6..527a322d56a 100644 --- a/compiler/rustc_target/src/spec/avr_gnu_base.rs +++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs @@ -45,6 +45,8 @@ pub fn target(target_cpu: String) -> TargetResult { late_link_args: vec![(LinkerFlavor::Gcc, vec!["-lgcc".to_owned()])] .into_iter() .collect(), + max_atomic_width: Some(0), + atomic_cas: false, ..TargetOptions::default() }, }) |
