Skip to content

Commit ea21839

Browse files
committed
Auto merge of #108145 - matthiaskrgr:rollup-bgadak1, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #104068 (rustdoc: Add PartialOrd trait to doc comment explanation) - #107489 (Implement partial support for non-lifetime binders) - #107905 (Pass arguments to `x` subcommands with `--`) - #108009 (Move some tests) - #108086 (wasm: Register the `relaxed-simd` target feature) - #108104 (don't into self) - #108133 (Small cleanups around `EarlyBinder`) - #108136 (Do not ICE on unmet trait alias impl bounds) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 947b696 + ecdb7bc commit ea21839

File tree

95 files changed

+822
-370
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+822
-370
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

-34
Original file line numberDiff line numberDiff line change
@@ -294,27 +294,6 @@ impl<'a> AstValidator<'a> {
294294
}
295295
}
296296

297-
fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) {
298-
// Check only lifetime parameters are present and that the lifetime
299-
// parameters that are present have no bounds.
300-
let non_lt_param_spans: Vec<_> = params
301-
.iter()
302-
.filter_map(|param| match param.kind {
303-
GenericParamKind::Lifetime { .. } => {
304-
if !param.bounds.is_empty() {
305-
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
306-
self.session.emit_err(ForbiddenLifetimeBound { spans });
307-
}
308-
None
309-
}
310-
_ => Some(param.ident.span),
311-
})
312-
.collect();
313-
if !non_lt_param_spans.is_empty() {
314-
self.session.emit_err(ForbiddenNonLifetimeParam { spans: non_lt_param_spans });
315-
}
316-
}
317-
318297
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
319298
self.check_decl_num_args(fn_decl);
320299
self.check_decl_cvaradic_pos(fn_decl);
@@ -745,7 +724,6 @@ impl<'a> AstValidator<'a> {
745724
)
746725
.emit();
747726
});
748-
self.check_late_bound_lifetime_defs(&bfty.generic_params);
749727
if let Extern::Implicit(_) = bfty.ext {
750728
let sig_span = self.session.source_map().next_point(ty.span.shrink_to_lo());
751729
self.maybe_lint_missing_abi(sig_span, ty.id);
@@ -1318,9 +1296,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13181296
for predicate in &generics.where_clause.predicates {
13191297
match predicate {
13201298
WherePredicate::BoundPredicate(bound_pred) => {
1321-
// A type binding, eg `for<'c> Foo: Send+Clone+'c`
1322-
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
1323-
13241299
// This is slightly complicated. Our representation for poly-trait-refs contains a single
13251300
// binder and thus we only allow a single level of quantification. However,
13261301
// the syntax of Rust permits quantification in two places in where clauses,
@@ -1396,11 +1371,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13961371
visit::walk_param_bound(self, bound)
13971372
}
13981373

1399-
fn visit_poly_trait_ref(&mut self, t: &'a PolyTraitRef) {
1400-
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
1401-
visit::walk_poly_trait_ref(self, t);
1402-
}
1403-
14041374
fn visit_variant_data(&mut self, s: &'a VariantData) {
14051375
self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s))
14061376
}
@@ -1437,10 +1407,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
14371407
.emit();
14381408
}
14391409

1440-
if let FnKind::Closure(ClosureBinder::For { generic_params, .. }, ..) = fk {
1441-
self.check_late_bound_lifetime_defs(generic_params);
1442-
}
1443-
14441410
if let FnKind::Fn(
14451411
_,
14461412
_,

compiler/rustc_ast_passes/src/feature_gate.rs

+54-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use rustc_span::symbol::sym;
1111
use rustc_span::Span;
1212
use rustc_target::spec::abi;
1313

14+
use crate::errors::ForbiddenLifetimeBound;
15+
1416
macro_rules! gate_feature_fn {
1517
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{
1618
let (visitor, has_feature, span, name, explain, help) =
@@ -136,6 +138,34 @@ impl<'a> PostExpansionVisitor<'a> {
136138
}
137139
ImplTraitVisitor { vis: self }.visit_ty(ty);
138140
}
141+
142+
fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) {
143+
// Check only lifetime parameters are present and that the lifetime
144+
// parameters that are present have no bounds.
145+
let non_lt_param_spans: Vec<_> = params
146+
.iter()
147+
.filter_map(|param| match param.kind {
148+
ast::GenericParamKind::Lifetime { .. } => None,
149+
_ => Some(param.ident.span),
150+
})
151+
.collect();
152+
// FIXME: gate_feature_post doesn't really handle multispans...
153+
if !non_lt_param_spans.is_empty() && !self.features.non_lifetime_binders {
154+
feature_err(
155+
&self.sess.parse_sess,
156+
sym::non_lifetime_binders,
157+
non_lt_param_spans,
158+
rustc_errors::fluent::ast_passes_forbidden_non_lifetime_param,
159+
)
160+
.emit();
161+
}
162+
for param in params {
163+
if !param.bounds.is_empty() {
164+
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
165+
self.sess.emit_err(ForbiddenLifetimeBound { spans });
166+
}
167+
}
168+
}
139169
}
140170

141171
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
@@ -147,7 +177,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
147177
..
148178
}) = attr_info
149179
{
150-
gate_feature_fn!(self, has_feature, attr.span, *name, descr);
180+
gate_feature_fn!(self, has_feature, attr.span, *name, *descr);
151181
}
152182
// Check unstable flavors of the `#[doc]` attribute.
153183
if attr.has_name(sym::doc) {
@@ -306,6 +336,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
306336
ast::TyKind::BareFn(bare_fn_ty) => {
307337
// Function pointers cannot be `const`
308338
self.check_extern(bare_fn_ty.ext, ast::Const::No);
339+
self.check_late_bound_lifetime_defs(&bare_fn_ty.generic_params);
309340
}
310341
ast::TyKind::Never => {
311342
gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental");
@@ -318,6 +349,19 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
318349
visit::walk_ty(self, ty)
319350
}
320351

352+
fn visit_generics(&mut self, g: &'a ast::Generics) {
353+
for predicate in &g.where_clause.predicates {
354+
match predicate {
355+
ast::WherePredicate::BoundPredicate(bound_pred) => {
356+
// A type binding, eg `for<'c> Foo: Send+Clone+'c`
357+
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
358+
}
359+
_ => {}
360+
}
361+
}
362+
visit::walk_generics(self, g);
363+
}
364+
321365
fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) {
322366
if let ast::FnRetTy::Ty(output_ty) = ret_ty {
323367
if let ast::TyKind::Never = output_ty.kind {
@@ -437,12 +481,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
437481
visit::walk_pat(self, pattern)
438482
}
439483

484+
fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) {
485+
self.check_late_bound_lifetime_defs(&t.bound_generic_params);
486+
visit::walk_poly_trait_ref(self, t);
487+
}
488+
440489
fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) {
441490
if let Some(header) = fn_kind.header() {
442491
// Stability of const fn methods are covered in `visit_assoc_item` below.
443492
self.check_extern(header.ext, header.constness);
444493
}
445494

495+
if let FnKind::Closure(ast::ClosureBinder::For { generic_params, .. }, ..) = fn_kind {
496+
self.check_late_bound_lifetime_defs(generic_params);
497+
}
498+
446499
if fn_kind.ctxt() != Some(FnCtxt::Foreign) && fn_kind.decl().c_variadic() {
447500
gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
448501
}

compiler/rustc_attr/src/builtin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ pub fn eval_condition(
731731
sess,
732732
sym::cfg_target_compact,
733733
cfg.span,
734-
&"compact `cfg(target(..))` is experimental and subject to change"
734+
"compact `cfg(target(..))` is experimental and subject to change"
735735
).emit();
736736
}
737737

compiler/rustc_codegen_ssa/src/target_features.rs

+1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
286286
("mutable-globals", Some(sym::wasm_target_feature)),
287287
("nontrapping-fptoint", Some(sym::wasm_target_feature)),
288288
("reference-types", Some(sym::wasm_target_feature)),
289+
("relaxed-simd", Some(sym::wasm_target_feature)),
289290
("sign-ext", Some(sym::wasm_target_feature)),
290291
("simd128", None),
291292
// tidy-alphabetical-end

compiler/rustc_feature/src/active.rs

+2
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ declare_features! (
473473
(active, no_sanitize, "1.42.0", Some(39699), None),
474474
/// Allows using the `non_exhaustive_omitted_patterns` lint.
475475
(active, non_exhaustive_omitted_patterns_lint, "1.57.0", Some(89554), None),
476+
/// Allows `for<T>` binders in where-clauses
477+
(incomplete, non_lifetime_binders, "CURRENT_RUSTC_VERSION", Some(1), None),
476478
/// Allows making `dyn Trait` well-formed even if `Trait` is not object safe.
477479
/// In that case, `dyn Trait: Trait` does not hold. Moreover, coercions and
478480
/// casts in safe Rust to `dyn Trait` for such a `Trait` is also forbidden.

compiler/rustc_hir_analysis/src/astconv/mod.rs

+75-16
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::errors::{
1414
AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits,
1515
TypeofReservedKeywordUsed, ValueOfAssociatedStructAlreadySpecified,
1616
};
17-
use crate::middle::resolve_lifetime as rl;
17+
use crate::middle::resolve_bound_vars as rbv;
1818
use crate::require_c_abi_if_c_variadic;
1919
use rustc_ast::TraitObjectSyntax;
2020
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -225,10 +225,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
225225
let tcx = self.tcx();
226226
let lifetime_name = |def_id| tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id));
227227

228-
match tcx.named_region(lifetime.hir_id) {
229-
Some(rl::Region::Static) => tcx.lifetimes.re_static,
228+
match tcx.named_bound_var(lifetime.hir_id) {
229+
Some(rbv::ResolvedArg::StaticLifetime) => tcx.lifetimes.re_static,
230230

231-
Some(rl::Region::LateBound(debruijn, index, def_id)) => {
231+
Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
232232
let name = lifetime_name(def_id.expect_local());
233233
let br = ty::BoundRegion {
234234
var: ty::BoundVar::from_u32(index),
@@ -237,15 +237,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
237237
tcx.mk_re_late_bound(debruijn, br)
238238
}
239239

240-
Some(rl::Region::EarlyBound(def_id)) => {
240+
Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
241241
let name = tcx.hir().ty_param_name(def_id.expect_local());
242242
let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
243243
let generics = tcx.generics_of(item_def_id);
244244
let index = generics.param_def_id_to_index[&def_id];
245245
tcx.mk_re_early_bound(ty::EarlyBoundRegion { def_id, index, name })
246246
}
247247

248-
Some(rl::Region::Free(scope, id)) => {
248+
Some(rbv::ResolvedArg::Free(scope, id)) => {
249249
let name = lifetime_name(id.expect_local());
250250
tcx.mk_re_free(scope, ty::BrNamed(id, name))
251251

@@ -1607,7 +1607,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16071607
self.ast_region_to_region(lifetime, None)
16081608
} else {
16091609
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
1610-
if tcx.named_region(lifetime.hir_id).is_some() {
1610+
if tcx.named_bound_var(lifetime.hir_id).is_some() {
16111611
self.ast_region_to_region(lifetime, None)
16121612
} else {
16131613
self.re_infer(None, span).unwrap_or_else(|| {
@@ -2600,6 +2600,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
26002600
&self,
26012601
opt_self_ty: Option<Ty<'tcx>>,
26022602
path: &hir::Path<'_>,
2603+
hir_id: hir::HirId,
26032604
permit_variants: bool,
26042605
) -> Ty<'tcx> {
26052606
let tcx = self.tcx();
@@ -2663,11 +2664,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
26632664
}
26642665
});
26652666

2666-
let def_id = def_id.expect_local();
2667-
let item_def_id = tcx.hir().ty_param_owner(def_id);
2668-
let generics = tcx.generics_of(item_def_id);
2669-
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2670-
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
2667+
match tcx.named_bound_var(hir_id) {
2668+
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
2669+
let name =
2670+
tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
2671+
let br = ty::BoundTy {
2672+
var: ty::BoundVar::from_u32(index),
2673+
kind: ty::BoundTyKind::Param(def_id, name),
2674+
};
2675+
tcx.mk_ty(ty::Bound(debruijn, br))
2676+
}
2677+
Some(rbv::ResolvedArg::EarlyBound(_)) => {
2678+
let def_id = def_id.expect_local();
2679+
let item_def_id = tcx.hir().ty_param_owner(def_id);
2680+
let generics = tcx.generics_of(item_def_id);
2681+
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2682+
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
2683+
}
2684+
arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2685+
}
26712686
}
26722687
Res::SelfTyParam { .. } => {
26732688
// `Self` in trait or type alias.
@@ -2870,27 +2885,50 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28702885
hir::TyKind::BareFn(bf) => {
28712886
require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
28722887

2873-
tcx.mk_fn_ptr(self.ty_of_fn(
2888+
let fn_ptr_ty = tcx.mk_fn_ptr(self.ty_of_fn(
28742889
ast_ty.hir_id,
28752890
bf.unsafety,
28762891
bf.abi,
28772892
bf.decl,
28782893
None,
28792894
Some(ast_ty),
2880-
))
2895+
));
2896+
2897+
if let Some(guar) =
2898+
deny_non_region_late_bound(tcx, bf.generic_params, "function pointer")
2899+
{
2900+
tcx.ty_error_with_guaranteed(guar)
2901+
} else {
2902+
fn_ptr_ty
2903+
}
28812904
}
28822905
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
28832906
self.maybe_lint_bare_trait(ast_ty, in_path);
28842907
let repr = match repr {
28852908
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
28862909
TraitObjectSyntax::DynStar => ty::DynStar,
28872910
};
2888-
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed, repr)
2911+
2912+
let object_ty = self.conv_object_ty_poly_trait_ref(
2913+
ast_ty.span,
2914+
bounds,
2915+
lifetime,
2916+
borrowed,
2917+
repr,
2918+
);
2919+
2920+
if let Some(guar) = bounds.iter().find_map(|trait_ref| {
2921+
deny_non_region_late_bound(tcx, trait_ref.bound_generic_params, "trait object")
2922+
}) {
2923+
tcx.ty_error_with_guaranteed(guar)
2924+
} else {
2925+
object_ty
2926+
}
28892927
}
28902928
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
28912929
debug!(?maybe_qself, ?path);
28922930
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
2893-
self.res_to_ty(opt_self_ty, path, false)
2931+
self.res_to_ty(opt_self_ty, path, ast_ty.hir_id, false)
28942932
}
28952933
&hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
28962934
let opaque_ty = tcx.hir().item(item_id);
@@ -3346,3 +3384,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
33463384
}
33473385
}
33483386
}
3387+
3388+
fn deny_non_region_late_bound(
3389+
tcx: TyCtxt<'_>,
3390+
params: &[hir::GenericParam<'_>],
3391+
where_: &str,
3392+
) -> Option<ErrorGuaranteed> {
3393+
params.iter().find_map(|bad_param| {
3394+
let what = match bad_param.kind {
3395+
hir::GenericParamKind::Type { .. } => "type",
3396+
hir::GenericParamKind::Const { .. } => "const",
3397+
hir::GenericParamKind::Lifetime { .. } => return None,
3398+
};
3399+
3400+
let mut diag = tcx.sess.struct_span_err(
3401+
bad_param.span,
3402+
format!("late-bound {what} parameter not allowed on {where_} types"),
3403+
);
3404+
3405+
Some(if tcx.features().non_lifetime_binders { diag.emit() } else { diag.delay_as_bug() })
3406+
})
3407+
}

compiler/rustc_hir_analysis/src/collect.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ use std::iter;
4141

4242
mod generics_of;
4343
mod item_bounds;
44-
mod lifetimes;
4544
mod predicates_of;
45+
mod resolve_bound_vars;
4646
mod type_of;
4747

4848
///////////////////////////////////////////////////////////////////////////
@@ -53,7 +53,7 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
5353
}
5454

5555
pub fn provide(providers: &mut Providers) {
56-
lifetimes::provide(providers);
56+
resolve_bound_vars::provide(providers);
5757
*providers = Providers {
5858
opt_const_param_of: type_of::opt_const_param_of,
5959
type_of: type_of::type_of,

0 commit comments

Comments
 (0)