Skip to content

Commit 0da281b

Browse files
committed
Auto merge of rust-lang#103623 - matthiaskrgr:rollup-318yc1t, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - rust-lang#103035 (Even nicer errors from assert_unsafe_precondition) - rust-lang#103106 (Try to say that memory outside the AM is always exposed) - rust-lang#103475 (Make param index generation a bit more robust) - rust-lang#103525 (Move a wf-check into the site where the value is instantiated) - rust-lang#103564 (library: allow some unused things in Miri) - rust-lang#103586 (Process registered region obligation in `resolve_regions_with_wf_tys`) - rust-lang#103592 (rustdoc: remove redundant CSS selector `.notable-traits .notable`) - rust-lang#103593 (Remove an unused parser function (`Expr::returns`)) - rust-lang#103611 (Add test for issue 103574) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9dd3d29 + 2252f7a commit 0da281b

36 files changed

+431
-140
lines changed

compiler/rustc_ast/src/ast.rs

-18
Original file line numberDiff line numberDiff line change
@@ -1112,24 +1112,6 @@ pub struct Expr {
11121112
}
11131113

11141114
impl Expr {
1115-
/// Returns `true` if this expression would be valid somewhere that expects a value;
1116-
/// for example, an `if` condition.
1117-
pub fn returns(&self) -> bool {
1118-
if let ExprKind::Block(ref block, _) = self.kind {
1119-
match block.stmts.last().map(|last_stmt| &last_stmt.kind) {
1120-
// Implicit return
1121-
Some(StmtKind::Expr(_)) => true,
1122-
// Last statement is an explicit return?
1123-
Some(StmtKind::Semi(expr)) => matches!(expr.kind, ExprKind::Ret(_)),
1124-
// This is a block that doesn't end in either an implicit or explicit return.
1125-
_ => false,
1126-
}
1127-
} else {
1128-
// This is not a block, it is a value.
1129-
true
1130-
}
1131-
}
1132-
11331115
/// Is this expr either `N`, or `{ N }`.
11341116
///
11351117
/// If this is not the case, name resolution does not resolve `N` when using

compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl

+9
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,12 @@ hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(l
137137
hir_analysis_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
138138
139139
hir_analysis_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function
140+
141+
hir_analysis_const_impl_for_non_const_trait =
142+
const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]`
143+
.suggestion = mark `{$trait_name}` as const
144+
.note = marking a trait with `#[const_trait]` ensures all default method bodies are `const`
145+
.adding = adding a non-const method body in the future would be a breaking change
146+
147+
hir_analysis_const_bound_for_non_const_trait =
148+
~const can only be applied to `#[const_trait]` traits

compiler/rustc_hir_analysis/src/astconv/mod.rs

+50-18
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECT
3636
use rustc_span::edition::Edition;
3737
use rustc_span::lev_distance::find_best_match_for_name;
3838
use rustc_span::symbol::{kw, Ident, Symbol};
39-
use rustc_span::Span;
39+
use rustc_span::{sym, Span};
4040
use rustc_target::spec::abi;
4141
use rustc_trait_selection::traits;
4242
use rustc_trait_selection::traits::astconv_object_safety_violations;
@@ -275,6 +275,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
275275
item_segment.args(),
276276
item_segment.infer_args,
277277
None,
278+
None,
278279
);
279280
if let Some(b) = item_segment.args().bindings.first() {
280281
Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
@@ -324,6 +325,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
324325
generic_args: &'a hir::GenericArgs<'_>,
325326
infer_args: bool,
326327
self_ty: Option<Ty<'tcx>>,
328+
constness: Option<ty::BoundConstness>,
327329
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
328330
// If the type is parameterized by this region, then replace this
329331
// region with the current anon region binding (in other words,
@@ -534,6 +536,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
534536
&mut substs_ctx,
535537
);
536538

539+
if let Some(ty::BoundConstness::ConstIfConst) = constness
540+
&& generics.has_self && !tcx.has_attr(def_id, sym::const_trait)
541+
{
542+
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
543+
}
544+
537545
(substs, arg_count)
538546
}
539547

@@ -601,6 +609,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
601609
item_segment.args(),
602610
item_segment.infer_args,
603611
None,
612+
None,
604613
);
605614

606615
if let Some(b) = item_segment.args().bindings.first() {
@@ -620,6 +629,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
620629
&self,
621630
trait_ref: &hir::TraitRef<'_>,
622631
self_ty: Ty<'tcx>,
632+
constness: ty::BoundConstness,
623633
) -> ty::TraitRef<'tcx> {
624634
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
625635

@@ -629,6 +639,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
629639
self_ty,
630640
trait_ref.path.segments.last().unwrap(),
631641
true,
642+
Some(constness),
632643
)
633644
}
634645

@@ -655,6 +666,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
655666
args,
656667
infer_args,
657668
Some(self_ty),
669+
Some(constness),
658670
);
659671

660672
let tcx = self.tcx();
@@ -680,6 +692,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
680692
speculative,
681693
&mut dup_bindings,
682694
binding_span.unwrap_or(binding.span),
695+
constness,
683696
);
684697
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
685698
}
@@ -783,13 +796,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
783796
self_ty: Ty<'tcx>,
784797
trait_segment: &hir::PathSegment<'_>,
785798
is_impl: bool,
799+
constness: Option<ty::BoundConstness>,
786800
) -> ty::TraitRef<'tcx> {
787801
let (substs, _) = self.create_substs_for_ast_trait_ref(
788802
span,
789803
trait_def_id,
790804
self_ty,
791805
trait_segment,
792806
is_impl,
807+
constness,
793808
);
794809
if let Some(b) = trait_segment.args().bindings.first() {
795810
Self::prohibit_assoc_ty_binding(self.tcx(), b.span);
@@ -805,6 +820,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
805820
self_ty: Ty<'tcx>,
806821
trait_segment: &'a hir::PathSegment<'a>,
807822
is_impl: bool,
823+
constness: Option<ty::BoundConstness>,
808824
) -> (SubstsRef<'tcx>, GenericArgCountResult) {
809825
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
810826

@@ -816,6 +832,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
816832
trait_segment.args(),
817833
trait_segment.infer_args,
818834
Some(self_ty),
835+
constness,
819836
)
820837
}
821838

@@ -1027,6 +1044,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10271044
speculative: bool,
10281045
dup_bindings: &mut FxHashMap<DefId, Span>,
10291046
path_span: Span,
1047+
constness: ty::BoundConstness,
10301048
) -> Result<(), ErrorGuaranteed> {
10311049
// Given something like `U: SomeTrait<T = X>`, we want to produce a
10321050
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
@@ -1122,10 +1140,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11221140
trait_ref.substs,
11231141
);
11241142

1125-
debug!(
1126-
"add_predicates_for_ast_type_binding: substs for trait-ref and assoc_item: {:?}",
1127-
substs_trait_ref_and_assoc_item
1128-
);
1143+
debug!(?substs_trait_ref_and_assoc_item);
11291144

11301145
ty::ProjectionTy {
11311146
item_def_id: assoc_item.def_id,
@@ -1146,8 +1161,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
11461161
tcx.collect_constrained_late_bound_regions(&projection_ty);
11471162
let late_bound_in_ty =
11481163
tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty));
1149-
debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref);
1150-
debug!("late_bound_in_ty = {:?}", late_bound_in_ty);
1164+
debug!(?late_bound_in_trait_ref);
1165+
debug!(?late_bound_in_ty);
11511166

11521167
// FIXME: point at the type params that don't have appropriate lifetimes:
11531168
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
@@ -1648,6 +1663,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16481663

16491664
// Checks that `bounds` contains exactly one element and reports appropriate
16501665
// errors otherwise.
1666+
#[instrument(level = "debug", skip(self, all_candidates, ty_param_name, is_equality), ret)]
16511667
fn one_bound_for_assoc_type<I>(
16521668
&self,
16531669
all_candidates: impl Fn() -> I,
@@ -1677,10 +1693,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16771693
return Err(reported);
16781694
}
16791695
};
1680-
debug!("one_bound_for_assoc_type: bound = {:?}", bound);
1696+
debug!(?bound);
16811697

16821698
if let Some(bound2) = next_cand {
1683-
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
1699+
debug!(?bound2);
16841700

16851701
let is_equality = is_equality();
16861702
let bounds = IntoIterator::into_iter([bound, bound2]).chain(matching_candidates);
@@ -1776,6 +1792,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
17761792
// parameter or `Self`.
17771793
// NOTE: When this function starts resolving `Trait::AssocTy` successfully
17781794
// it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
1795+
#[instrument(level = "debug", skip(self, hir_ref_id, span, qself, assoc_segment), fields(assoc_ident=?assoc_segment.ident), ret)]
17791796
pub fn associated_path_to_ty(
17801797
&self,
17811798
hir_ref_id: hir::HirId,
@@ -1793,8 +1810,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
17931810
Res::Err
17941811
};
17951812

1796-
debug!("associated_path_to_ty: {:?}::{}", qself_ty, assoc_ident);
1797-
17981813
// Check if we have an enum variant.
17991814
let mut variant_resolution = None;
18001815
if let ty::Adt(adt_def, _) = qself_ty.kind() {
@@ -2050,6 +2065,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
20502065
item_def_id: DefId,
20512066
trait_segment: &hir::PathSegment<'_>,
20522067
item_segment: &hir::PathSegment<'_>,
2068+
constness: ty::BoundConstness,
20532069
) -> Ty<'tcx> {
20542070
let tcx = self.tcx();
20552071

@@ -2094,8 +2110,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
20942110

20952111
debug!("qpath_to_ty: self_type={:?}", self_ty);
20962112

2097-
let trait_ref =
2098-
self.ast_path_to_mono_trait_ref(span, trait_def_id, self_ty, trait_segment, false);
2113+
let trait_ref = self.ast_path_to_mono_trait_ref(
2114+
span,
2115+
trait_def_id,
2116+
self_ty,
2117+
trait_segment,
2118+
false,
2119+
Some(constness),
2120+
);
20992121

21002122
let item_substs = self.create_substs_for_associated_item(
21012123
span,
@@ -2534,12 +2556,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25342556
Res::Def(DefKind::AssocTy, def_id) => {
25352557
debug_assert!(path.segments.len() >= 2);
25362558
self.prohibit_generics(path.segments[..path.segments.len() - 2].iter(), |_| {});
2559+
// HACK: until we support `<Type as ~const Trait>`, assume all of them are.
2560+
let constness = if tcx.has_attr(tcx.parent(def_id), sym::const_trait) {
2561+
ty::BoundConstness::ConstIfConst
2562+
} else {
2563+
ty::BoundConstness::NotConst
2564+
};
25372565
self.qpath_to_ty(
25382566
span,
25392567
opt_self_ty,
25402568
def_id,
25412569
&path.segments[path.segments.len() - 2],
25422570
path.segments.last().unwrap(),
2571+
constness,
25432572
)
25442573
}
25452574
Res::PrimTy(prim_ty) => {
@@ -2658,6 +2687,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
26582687
&GenericArgs::none(),
26592688
true,
26602689
None,
2690+
None,
26612691
);
26622692
EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id)))
26632693
.subst(tcx, substs)
@@ -2766,6 +2796,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
27662796
}
27672797
}
27682798

2799+
#[instrument(level = "debug", skip(self, hir_id, unsafety, abi, decl, generics, hir_ty), ret)]
27692800
pub fn ty_of_fn(
27702801
&self,
27712802
hir_id: hir::HirId,
@@ -2775,8 +2806,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
27752806
generics: Option<&hir::Generics<'_>>,
27762807
hir_ty: Option<&hir::Ty<'_>>,
27772808
) -> ty::PolyFnSig<'tcx> {
2778-
debug!("ty_of_fn");
2779-
27802809
let tcx = self.tcx();
27812810
let bound_vars = tcx.late_bound_vars(hir_id);
27822811
debug!(?bound_vars);
@@ -2826,7 +2855,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28262855
hir::FnRetTy::DefaultReturn(..) => tcx.mk_unit(),
28272856
};
28282857

2829-
debug!("ty_of_fn: output_ty={:?}", output_ty);
2858+
debug!(?output_ty);
28302859

28312860
let fn_ty = tcx.mk_fn_sig(input_tys.into_iter(), output_ty, decl.c_variadic, unsafety, abi);
28322861
let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
@@ -2903,8 +2932,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
29032932
let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) =
29042933
hir.get(hir.get_parent_node(fn_hir_id)) else { bug!("ImplItem should have Impl parent") };
29052934

2906-
let trait_ref =
2907-
self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
2935+
let trait_ref = self.instantiate_mono_trait_ref(
2936+
i.of_trait.as_ref()?,
2937+
self.ast_ty_to_ty(i.self_ty),
2938+
ty::BoundConstness::NotConst,
2939+
);
29082940

29092941
let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
29102942
tcx,

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+4
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,10 @@ fn resolve_regions_with_wf_tys<'tcx>(
713713

714714
add_constraints(&infcx, region_bound_pairs);
715715

716+
infcx.process_registered_region_obligations(
717+
outlives_environment.region_bound_pairs(),
718+
param_env,
719+
);
716720
let errors = infcx.resolve_regions(&outlives_environment);
717721

718722
debug!(?errors, "errors");

compiler/rustc_hir_analysis/src/collect.rs

+34-3
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
11431143
}
11441144

11451145
ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
1146-
// Do not try to inference the return type for a impl method coming from a trait
1146+
// Do not try to infer the return type for a impl method coming from a trait
11471147
if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) =
11481148
tcx.hir().get(tcx.hir().get_parent_node(hir_id))
11491149
&& i.of_trait.is_some()
@@ -1286,15 +1286,46 @@ fn infer_return_ty_for_fn_sig<'tcx>(
12861286

12871287
fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
12881288
let icx = ItemCtxt::new(tcx, def_id);
1289-
match tcx.hir().expect_item(def_id.expect_local()).kind {
1289+
let item = tcx.hir().expect_item(def_id.expect_local());
1290+
match item.kind {
12901291
hir::ItemKind::Impl(ref impl_) => impl_.of_trait.as_ref().map(|ast_trait_ref| {
12911292
let selfty = tcx.type_of(def_id);
1292-
<dyn AstConv<'_>>::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
1293+
<dyn AstConv<'_>>::instantiate_mono_trait_ref(
1294+
&icx,
1295+
ast_trait_ref,
1296+
selfty,
1297+
check_impl_constness(tcx, impl_.constness, ast_trait_ref),
1298+
)
12931299
}),
12941300
_ => bug!(),
12951301
}
12961302
}
12971303

1304+
fn check_impl_constness(
1305+
tcx: TyCtxt<'_>,
1306+
constness: hir::Constness,
1307+
ast_trait_ref: &hir::TraitRef<'_>,
1308+
) -> ty::BoundConstness {
1309+
match constness {
1310+
hir::Constness::Const => {
1311+
if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
1312+
let trait_name = tcx.item_name(trait_def_id).to_string();
1313+
tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
1314+
trait_ref_span: ast_trait_ref.path.span,
1315+
trait_name,
1316+
local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
1317+
marking: (),
1318+
adding: (),
1319+
});
1320+
ty::BoundConstness::NotConst
1321+
} else {
1322+
ty::BoundConstness::ConstIfConst
1323+
}
1324+
},
1325+
hir::Constness::NotConst => ty::BoundConstness::NotConst,
1326+
}
1327+
}
1328+
12981329
fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
12991330
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
13001331
let item = tcx.hir().expect_item(def_id.expect_local());

0 commit comments

Comments
 (0)