diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl | 9 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/astconv/mod.rs | 68 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/wfcheck.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect/generics_of.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/errors.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_lexer/src/lib.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/wf.rs | 26 |
10 files changed, 152 insertions, 83 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7112c267577..4ef43735a62 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1112,24 +1112,6 @@ pub struct Expr { } impl Expr { - /// Returns `true` if this expression would be valid somewhere that expects a value; - /// for example, an `if` condition. - pub fn returns(&self) -> bool { - if let ExprKind::Block(ref block, _) = self.kind { - match block.stmts.last().map(|last_stmt| &last_stmt.kind) { - // Implicit return - Some(StmtKind::Expr(_)) => true, - // Last statement is an explicit return? - Some(StmtKind::Semi(expr)) => matches!(expr.kind, ExprKind::Ret(_)), - // This is a block that doesn't end in either an implicit or explicit return. - _ => false, - } - } else { - // This is not a block, it is a value. - true - } - } - /// Is this expr either `N`, or `{ N }`. /// /// If this is not the case, name resolution does not resolve `N` when using diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl index 357c6900a70..7ac44312695 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl @@ -137,3 +137,12 @@ hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(l hir_analysis_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` hir_analysis_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function + +hir_analysis_const_impl_for_non_const_trait = + const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]` + .suggestion = mark `{$trait_name}` as const + .note = marking a trait with `#[const_trait]` ensures all default method bodies are `const` + .adding = adding a non-const method body in the future would be a breaking change + +hir_analysis_const_bound_for_non_const_trait = + ~const can only be applied to `#[const_trait]` traits diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index a0350c26d82..6baf9844977 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -36,7 +36,7 @@ use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECT use rustc_span::edition::Edition; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{sym, Span}; use rustc_target::spec::abi; use rustc_trait_selection::traits; use rustc_trait_selection::traits::astconv_object_safety_violations; @@ -275,6 +275,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.args(), item_segment.infer_args, None, + None, ); if let Some(b) = item_segment.args().bindings.first() { Self::prohibit_assoc_ty_binding(self.tcx(), b.span); @@ -324,6 +325,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generic_args: &'a hir::GenericArgs<'_>, infer_args: bool, self_ty: Option<Ty<'tcx>>, + constness: Option<ty::BoundConstness>, ) -> (SubstsRef<'tcx>, GenericArgCountResult) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, @@ -534,6 +536,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &mut substs_ctx, ); + if let Some(ty::BoundConstness::ConstIfConst) = constness + && generics.has_self && !tcx.has_attr(def_id, sym::const_trait) + { + tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } ); + } + (substs, arg_count) } @@ -601,6 +609,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.args(), item_segment.infer_args, None, + None, ); if let Some(b) = item_segment.args().bindings.first() { @@ -620,6 +629,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &self, trait_ref: &hir::TraitRef<'_>, self_ty: Ty<'tcx>, + constness: ty::BoundConstness, ) -> ty::TraitRef<'tcx> { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {}); @@ -629,6 +639,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_ref.path.segments.last().unwrap(), true, + Some(constness), ) } @@ -655,6 +666,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { args, infer_args, Some(self_ty), + Some(constness), ); let tcx = self.tcx(); @@ -680,6 +692,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { speculative, &mut dup_bindings, binding_span.unwrap_or(binding.span), + constness, ); // Okay to ignore `Err` because of `ErrorGuaranteed` (see above). } @@ -783,6 +796,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, trait_segment: &hir::PathSegment<'_>, is_impl: bool, + constness: Option<ty::BoundConstness>, ) -> ty::TraitRef<'tcx> { let (substs, _) = self.create_substs_for_ast_trait_ref( span, @@ -790,6 +804,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_segment, is_impl, + constness, ); if let Some(b) = trait_segment.args().bindings.first() { Self::prohibit_assoc_ty_binding(self.tcx(), b.span); @@ -805,6 +820,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty: Ty<'tcx>, trait_segment: &'a hir::PathSegment<'a>, is_impl: bool, + constness: Option<ty::BoundConstness>, ) -> (SubstsRef<'tcx>, GenericArgCountResult) { self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl); @@ -816,6 +832,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_segment.args(), trait_segment.infer_args, Some(self_ty), + constness, ) } @@ -1027,6 +1044,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { speculative: bool, dup_bindings: &mut FxHashMap<DefId, Span>, path_span: Span, + constness: ty::BoundConstness, ) -> Result<(), ErrorGuaranteed> { // Given something like `U: SomeTrait<T = X>`, we want to produce a // predicate like `<U as SomeTrait>::T = X`. This is somewhat @@ -1122,10 +1140,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_ref.substs, ); - debug!( - "add_predicates_for_ast_type_binding: substs for trait-ref and assoc_item: {:?}", - substs_trait_ref_and_assoc_item - ); + debug!(?substs_trait_ref_and_assoc_item); ty::ProjectionTy { item_def_id: assoc_item.def_id, @@ -1146,8 +1161,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.collect_constrained_late_bound_regions(&projection_ty); let late_bound_in_ty = tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty)); - debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); - debug!("late_bound_in_ty = {:?}", late_bound_in_ty); + debug!(?late_bound_in_trait_ref); + debug!(?late_bound_in_ty); // FIXME: point at the type params that don't have appropriate lifetimes: // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F); @@ -1648,6 +1663,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Checks that `bounds` contains exactly one element and reports appropriate // errors otherwise. + #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, is_equality), ret)] fn one_bound_for_assoc_type<I>( &self, all_candidates: impl Fn() -> I, @@ -1677,10 +1693,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { return Err(reported); } }; - debug!("one_bound_for_assoc_type: bound = {:?}", bound); + debug!(?bound); if let Some(bound2) = next_cand { - debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2); + debug!(?bound2); let is_equality = is_equality(); let bounds = IntoIterator::into_iter([bound, bound2]).chain(matching_candidates); @@ -1776,6 +1792,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // parameter or `Self`. // NOTE: When this function starts resolving `Trait::AssocTy` successfully // it should also start reporting the `BARE_TRAIT_OBJECTS` lint. + #[instrument(level = "debug", skip(self, hir_ref_id, span, qself, assoc_segment), fields(assoc_ident=?assoc_segment.ident), ret)] pub fn associated_path_to_ty( &self, hir_ref_id: hir::HirId, @@ -1793,8 +1810,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Res::Err }; - debug!("associated_path_to_ty: {:?}::{}", qself_ty, assoc_ident); - // Check if we have an enum variant. let mut variant_resolution = None; if let ty::Adt(adt_def, _) = qself_ty.kind() { @@ -2050,6 +2065,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_def_id: DefId, trait_segment: &hir::PathSegment<'_>, item_segment: &hir::PathSegment<'_>, + constness: ty::BoundConstness, ) -> Ty<'tcx> { let tcx = self.tcx(); @@ -2094,8 +2110,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("qpath_to_ty: self_type={:?}", self_ty); - let trait_ref = - self.ast_path_to_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false); + let trait_ref = self.ast_path_to_mono_trait_ref( + span, + trait_def_id, + self_ty, + trait_segment, + false, + Some(constness), + ); let item_substs = self.create_substs_for_associated_item( span, @@ -2534,12 +2556,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Res::Def(DefKind::AssocTy, def_id) => { debug_assert!(path.segments.len() >= 2); self.prohibit_generics(path.segments[..path.segments.len() - 2].iter(), |_| {}); + // HACK: until we support `<Type as ~const Trait>`, assume all of them are. + let constness = if tcx.has_attr(tcx.parent(def_id), sym::const_trait) { + ty::BoundConstness::ConstIfConst + } else { + ty::BoundConstness::NotConst + }; self.qpath_to_ty( span, opt_self_ty, def_id, &path.segments[path.segments.len() - 2], path.segments.last().unwrap(), + constness, ) } Res::PrimTy(prim_ty) => { @@ -2658,6 +2687,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &GenericArgs::none(), true, None, + None, ); EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id))) .subst(tcx, substs) @@ -2766,6 +2796,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } + #[instrument(level = "debug", skip(self, hir_id, unsafety, abi, decl, generics, hir_ty), ret)] pub fn ty_of_fn( &self, hir_id: hir::HirId, @@ -2775,8 +2806,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { generics: Option<&hir::Generics<'_>>, hir_ty: Option<&hir::Ty<'_>>, ) -> ty::PolyFnSig<'tcx> { - debug!("ty_of_fn"); - let tcx = self.tcx(); let bound_vars = tcx.late_bound_vars(hir_id); debug!(?bound_vars); @@ -2826,7 +2855,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir::FnRetTy::DefaultReturn(..) => tcx.mk_unit(), }; - debug!("ty_of_fn: output_ty={:?}", output_ty); + debug!(?output_ty); let fn_ty = tcx.mk_fn_sig(input_tys.into_iter(), output_ty, decl.c_variadic, unsafety, abi); let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars); @@ -2903,8 +2932,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) = hir.get(hir.get_parent_node(fn_hir_id)) else { bug!("ImplItem should have Impl parent") }; - let trait_ref = - self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty)); + let trait_ref = self.instantiate_mono_trait_ref( + i.of_trait.as_ref()?, + self.ast_ty_to_ty(i.self_ty), + ty::BoundConstness::NotConst, + ); let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind( tcx, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 33ed3b96aa8..70a171c02b2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -713,6 +713,10 @@ fn resolve_regions_with_wf_tys<'tcx>( add_constraints(&infcx, region_bound_pairs); + infcx.process_registered_region_obligations( + outlives_environment.region_bound_pairs(), + param_env, + ); let errors = infcx.resolve_regions(&outlives_environment); debug!(?errors, "errors"); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 66ca7d7aa08..e261bb07f95 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1143,7 +1143,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { } ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => { - // Do not try to inference the return type for a impl method coming from a trait + // Do not try to infer the return type for a impl method coming from a trait if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.hir().get(tcx.hir().get_parent_node(hir_id)) && i.of_trait.is_some() @@ -1286,15 +1286,46 @@ fn infer_return_ty_for_fn_sig<'tcx>( fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> { let icx = ItemCtxt::new(tcx, def_id); - match tcx.hir().expect_item(def_id.expect_local()).kind { + let item = tcx.hir().expect_item(def_id.expect_local()); + match item.kind { hir::ItemKind::Impl(ref impl_) => impl_.of_trait.as_ref().map(|ast_trait_ref| { let selfty = tcx.type_of(def_id); - <dyn AstConv<'_>>::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) + <dyn AstConv<'_>>::instantiate_mono_trait_ref( + &icx, + ast_trait_ref, + selfty, + check_impl_constness(tcx, impl_.constness, ast_trait_ref), + ) }), _ => bug!(), } } +fn check_impl_constness( + tcx: TyCtxt<'_>, + constness: hir::Constness, + ast_trait_ref: &hir::TraitRef<'_>, +) -> ty::BoundConstness { + match constness { + hir::Constness::Const => { + if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) { + let trait_name = tcx.item_name(trait_def_id).to_string(); + tcx.sess.emit_err(errors::ConstImplForNonConstTrait { + trait_ref_span: ast_trait_ref.path.span, + trait_name, + local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()), + marking: (), + adding: (), + }); + ty::BoundConstness::NotConst + } else { + ty::BoundConstness::ConstIfConst + } + }, + hir::Constness::NotConst => ty::BoundConstness::NotConst, + } +} + fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity { let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); let item = tcx.hir().expect_item(def_id.expect_local()); diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 707fd6c7527..c7777a94689 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -249,6 +249,11 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // Now create the real type and const parameters. let type_start = own_start - has_self as u32 + params.len() as u32; let mut i = 0; + let mut next_index = || { + let prev = i; + i += 1; + prev as u32 + type_start + }; const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \ `struct`, `enum`, `type`, or `trait` definitions"; @@ -278,15 +283,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic }; - let param_def = ty::GenericParamDef { - index: type_start + i as u32, + Some(ty::GenericParamDef { + index: next_index(), name: param.name.ident().name, def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), pure_wrt_drop: param.pure_wrt_drop, kind, - }; - i += 1; - Some(param_def) + }) } GenericParamKind::Const { default, .. } => { if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() { @@ -297,15 +300,13 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { ); } - let param_def = ty::GenericParamDef { - index: type_start + i as u32, + Some(ty::GenericParamDef { + index: next_index(), name: param.name.ident().name, def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), pure_wrt_drop: param.pure_wrt_drop, kind: ty::GenericParamDefKind::Const { has_default: default.is_some() }, - }; - i += 1; - Some(param_def) + }) } })); @@ -323,8 +324,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { &["<closure_kind>", "<closure_signature>", "<upvars>"][..] }; - params.extend(dummy_args.iter().enumerate().map(|(i, &arg)| ty::GenericParamDef { - index: type_start + i as u32, + params.extend(dummy_args.iter().map(|&arg| ty::GenericParamDef { + index: next_index(), name: Symbol::intern(arg), def_id, pure_wrt_drop: false, @@ -337,7 +338,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node { params.push(ty::GenericParamDef { - index: type_start, + index: next_index(), name: Symbol::intern("<const_ty>"), def_id, pure_wrt_drop: false, diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 9457da32ce6..bd0c1f5dd10 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -249,3 +249,24 @@ pub struct ExpectedUsedSymbol { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_const_impl_for_non_const_trait)] +pub struct ConstImplForNonConstTrait { + #[primary_span] + pub trait_ref_span: Span, + pub trait_name: String, + #[suggestion(applicability = "machine-applicable", code = "#[const_trait]")] + pub local_trait_span: Option<Span>, + #[note] + pub marking: (), + #[note(adding)] + pub adding: (), +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_const_bound_for_non_const_trait)] +pub struct ConstBoundForNonConstTrait { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index c71e6ffe34d..51515976e4e 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -57,29 +57,42 @@ pub enum TokenKind { // Multi-char tokens: /// "// comment" LineComment { doc_style: Option<DocStyle> }, + /// `/* block comment */` /// - /// Block comments can be recursive, so the sequence like `/* /* */` + /// Block comments can be recursive, so a sequence like `/* /* */` /// will not be considered terminated and will result in a parsing error. BlockComment { doc_style: Option<DocStyle>, terminated: bool }, - /// Any whitespace characters sequence. + + /// Any whitespace character sequence. Whitespace, + /// "ident" or "continue" - /// At this step keywords are also considered identifiers. + /// + /// At this step, keywords are also considered identifiers. Ident, + /// Like the above, but containing invalid unicode codepoints. InvalidIdent, + /// "r#ident" RawIdent, - /// An unknown prefix like `foo#`, `foo'`, `foo"`. Note that only the + + /// An unknown prefix, like `foo#`, `foo'`, `foo"`. + /// + /// Note that only the /// prefix (`foo`) is included in the token, not the separator (which is /// lexed as its own distinct token). In Rust 2021 and later, reserved /// prefixes are reported as errors; in earlier editions, they result in a /// (allowed by default) lint, and are treated as regular identifier /// tokens. UnknownPrefix, - /// "12_u8", "1.0e-40", "b"123"". See `LiteralKind` for more details. + + /// Examples: `"12_u8"`, `"1.0e-40"`, `b"123`. + /// + /// See [LiteralKind] for more details. Literal { kind: LiteralKind, suffix_start: u32 }, + /// "'a" Lifetime { starts_with_number: bool }, diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 879a3b660b4..18d37d95a83 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -69,7 +69,9 @@ extern "C" void LLVMInitializePasses() { initializeAnalysis(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); +#if LLVM_VERSION_LT(16, 0) initializeInstrumentation(Registry); +#endif initializeTarget(Registry); } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 0870833cc35..30feabe1a09 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -303,32 +303,6 @@ impl<'tcx> WfPredicates<'tcx> { let obligations = if trait_pred.constness == ty::BoundConstness::NotConst { self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs) } else { - if !tcx.has_attr(trait_ref.def_id, rustc_span::sym::const_trait) { - if let Some(item) = self.item && - let hir::ItemKind::Impl(impl_) = item.kind && - let Some(trait_) = &impl_.of_trait && - let Some(def_id) = trait_.trait_def_id() && - def_id == trait_ref.def_id - { - let trait_name = tcx.item_name(def_id); - let mut err = tcx.sess.struct_span_err( - self.span, - &format!("const `impl` for trait `{trait_name}` which is not marked with `#[const_trait]`"), - ); - if def_id.is_local() { - let sp = tcx.def_span(def_id).shrink_to_lo(); - err.span_suggestion(sp, &format!("mark `{trait_name}` as const"), "#[const_trait]", rustc_errors::Applicability::MachineApplicable); - } - err.note("marking a trait with `#[const_trait]` ensures all default method bodies are `const`"); - err.note("adding a non-const method body in the future would be a breaking change"); - err.emit(); - } else { - tcx.sess.span_err( - self.span, - "~const can only be applied to `#[const_trait]` traits", - ); - } - } self.nominal_obligations(trait_ref.def_id, trait_ref.substs) }; |
