diff options
| author | bors <bors@rust-lang.org> | 2024-07-22 03:31:16 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-22 03:31:16 +0000 |
| commit | ee0fd6caf770e8b3baa403b4da3ef0c7e274dc21 (patch) | |
| tree | 51ba530f78f3619f36a9fc858102ef074270302b /compiler | |
| parent | 0f8534e79e4cfbda7421017047d1f5021235b0ac (diff) | |
| parent | fdef1d959202b3269430fff1ac0b5e9dde746b3d (diff) | |
Auto merge of #128048 - workingjubilee:rollup-gehtjxd, r=workingjubilee
Rollup of 6 pull requests Successful merges: - #127583 (Deal with invalid UTF-8 from `gai_strerror`) - #128014 (Fix stab display in doc blocks) - #128020 (Just totally fully deny late-bound consts) - #128023 (rustdoc: short descriptions cause word-breaks in tables) - #128033 (Explain why we require `_` for empty patterns) - #128038 (Don't output incremental test artifacts into working directory) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_ast_passes/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/errors.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_ast_passes/src/feature_gate.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/rustc.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 6 |
7 files changed, 59 insertions, 23 deletions
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 8f7dd774207..ca0b7f2ac3a 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -120,6 +120,9 @@ ast_passes_fn_without_body = ast_passes_forbidden_bound = bounds cannot be used in this context +ast_passes_forbidden_const_param = + late-bound const parameters cannot be used currently + ast_passes_forbidden_default = `default` is only allowed on items in trait impls .label = `default` because of this diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 783bca6b695..215ccd2ab4d 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -70,6 +70,13 @@ pub struct ForbiddenBound { } #[derive(Diagnostic)] +#[diag(ast_passes_forbidden_const_param)] +pub struct ForbiddenConstParam { + #[primary_span] + pub const_param_spans: Vec<Span>, +} + +#[derive(Diagnostic)] #[diag(ast_passes_fn_param_too_many)] pub struct FnParamTooMany { #[primary_span] diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 2178b65727d..e91dfb27766 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -162,6 +162,22 @@ impl<'a> PostExpansionVisitor<'a> { crate::fluent_generated::ast_passes_forbidden_non_lifetime_param ); + // FIXME(non_lifetime_binders): Const bound params are pretty broken. + // Let's keep users from using this feature accidentally. + if self.features.non_lifetime_binders { + let const_param_spans: Vec<_> = params + .iter() + .filter_map(|param| match param.kind { + ast::GenericParamKind::Const { .. } => Some(param.ident.span), + _ => None, + }) + .collect(); + + if !const_param_spans.is_empty() { + self.sess.dcx().emit_err(errors::ForbiddenConstParam { const_param_spans }); + } + } + for param in params { if !param.bounds.is_empty() { let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 7930f54038d..349dc9ad00e 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -2094,11 +2094,7 @@ pub fn deny_non_region_late_bound( format!("late-bound {what} parameter not allowed on {where_}"), ); - let guar = if tcx.features().non_lifetime_binders && first { - diag.emit() - } else { - diag.delay_as_bug() - }; + let guar = diag.emit_unless(!tcx.features().non_lifetime_binders || !first); first = false; *arg = ResolvedArg::Error(guar); diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 70065b5a2c3..95799cec94b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -16,8 +16,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_pattern_analysis::errors::Uncovered; use rustc_pattern_analysis::rustc::{ - Constructor, DeconstructedPat, MatchArm, RustcPatCtxt as PatCtxt, Usefulness, UsefulnessReport, - WitnessPat, + Constructor, DeconstructedPat, MatchArm, RevealedTy, RustcPatCtxt as PatCtxt, Usefulness, + UsefulnessReport, WitnessPat, }; use rustc_session::lint::builtin::{ BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS, @@ -998,27 +998,31 @@ fn report_non_exhaustive_match<'p, 'tcx>( err.note(format!("the matched value is of type `{}`", scrut_ty)); if !is_empty_match { - let mut non_exhaustive_tys = FxIndexSet::default(); + let mut special_tys = FxIndexSet::default(); // Look at the first witness. - collect_non_exhaustive_tys(cx, &witnesses[0], &mut non_exhaustive_tys); + collect_special_tys(cx, &witnesses[0], &mut special_tys); - for ty in non_exhaustive_tys { + for ty in special_tys { if ty.is_ptr_sized_integral() { - if ty == cx.tcx.types.usize { + if ty.inner() == cx.tcx.types.usize { err.note(format!( "`{ty}` does not have a fixed maximum value, so half-open ranges are necessary to match \ exhaustively", )); - } else if ty == cx.tcx.types.isize { + } else if ty.inner() == cx.tcx.types.isize { err.note(format!( "`{ty}` does not have fixed minimum and maximum values, so half-open ranges are necessary to match \ exhaustively", )); } - } else if ty == cx.tcx.types.str_ { + } else if ty.inner() == cx.tcx.types.str_ { err.note("`&str` cannot be matched exhaustively, so a wildcard `_` is necessary"); - } else if cx.is_foreign_non_exhaustive_enum(cx.reveal_opaque_ty(ty)) { + } else if cx.is_foreign_non_exhaustive_enum(ty) { err.note(format!("`{ty}` is marked as non-exhaustive, so a wildcard `_` is necessary to match exhaustively")); + } else if cx.is_uninhabited(ty.inner()) && cx.tcx.features().min_exhaustive_patterns { + // The type is uninhabited yet there is a witness: we must be in the `MaybeInvalid` + // case. + err.note(format!("`{ty}` is uninhabited but is not being matched by value, so a wildcard `_` is required")); } } } @@ -1168,22 +1172,22 @@ fn joined_uncovered_patterns<'p, 'tcx>( } } -fn collect_non_exhaustive_tys<'tcx>( +/// Collect types that require specific explanations when they show up in witnesses. +fn collect_special_tys<'tcx>( cx: &PatCtxt<'_, 'tcx>, pat: &WitnessPat<'_, 'tcx>, - non_exhaustive_tys: &mut FxIndexSet<Ty<'tcx>>, + special_tys: &mut FxIndexSet<RevealedTy<'tcx>>, ) { - if matches!(pat.ctor(), Constructor::NonExhaustive) { - non_exhaustive_tys.insert(pat.ty().inner()); + if matches!(pat.ctor(), Constructor::NonExhaustive | Constructor::Never) { + special_tys.insert(*pat.ty()); } if let Constructor::IntRange(range) = pat.ctor() { if cx.is_range_beyond_boundaries(range, *pat.ty()) { // The range denotes the values before `isize::MIN` or the values after `usize::MAX`/`isize::MAX`. - non_exhaustive_tys.insert(pat.ty().inner()); + special_tys.insert(*pat.ty()); } } - pat.iter_fields() - .for_each(|field_pat| collect_non_exhaustive_tys(cx, field_pat, non_exhaustive_tys)) + pat.iter_fields().for_each(|field_pat| collect_special_tys(cx, field_pat, special_tys)) } fn report_adt_defined_here<'tcx>( diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index d17ee8bff50..6ef2d69273e 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -40,9 +40,15 @@ pub type WitnessPat<'p, 'tcx> = crate::pat::WitnessPat<RustcPatCtxt<'p, 'tcx>>; /// /// Use `.inner()` or deref to get to the `Ty<'tcx>`. #[repr(transparent)] -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct RevealedTy<'tcx>(Ty<'tcx>); +impl<'tcx> fmt::Display for RevealedTy<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(fmt) + } +} + impl<'tcx> fmt::Debug for RevealedTy<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(fmt) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dc7200465d9..51414d78596 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2763,7 +2763,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { let res = match kind { RibKind::Item(..) | RibKind::AssocItem => Res::Def(def_kind, def_id.to_def_id()), RibKind::Normal => { - if self.r.tcx.features().non_lifetime_binders { + // FIXME(non_lifetime_binders): Stop special-casing + // const params to error out here. + if self.r.tcx.features().non_lifetime_binders + && matches!(param.kind, GenericParamKind::Type { .. }) + { Res::Def(def_kind, def_id.to_def_id()) } else { Res::Err |
