Skip to content

Commit affe0d3

Browse files
committed
Auto merge of #100174 - Dylan-DPC:rollup-wnskbk6, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #99835 (Suggest adding/removing `ref` for binding patterns) - #100155 (Use `node_type_opt` to skip over generics that were not expected) - #100157 (rustdoc: use `collect()` instead of repeatedly pushing) - #100158 (kmc-solid: Add a stub implementation of #98246 (`File::set_times`)) - #100166 (Remove more Clean trait implementations) - #100168 (Improve diagnostics for `const a: = expr;`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents d77da9d + e7ed844 commit affe0d3

30 files changed

+414
-162
lines changed

compiler/rustc_parse/src/parser/item.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -1179,39 +1179,47 @@ impl<'a> Parser<'a> {
11791179

11801180
// Parse the type of a `const` or `static mut?` item.
11811181
// That is, the `":" $ty` fragment.
1182-
let ty = if self.eat(&token::Colon) {
1183-
self.parse_ty()?
1184-
} else {
1185-
self.recover_missing_const_type(id, m)
1182+
let ty = match (self.eat(&token::Colon), self.check(&token::Eq) | self.check(&token::Semi))
1183+
{
1184+
// If there wasn't a `:` or the colon was followed by a `=` or `;` recover a missing type.
1185+
(true, false) => self.parse_ty()?,
1186+
(colon, _) => self.recover_missing_const_type(colon, m),
11861187
};
11871188

11881189
let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None };
11891190
self.expect_semi()?;
11901191
Ok((id, ty, expr))
11911192
}
11921193

1193-
/// We were supposed to parse `:` but the `:` was missing.
1194+
/// We were supposed to parse `":" $ty` but the `:` or the type was missing.
11941195
/// This means that the type is missing.
1195-
fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
1196+
fn recover_missing_const_type(&mut self, colon_present: bool, m: Option<Mutability>) -> P<Ty> {
11961197
// Construct the error and stash it away with the hope
11971198
// that typeck will later enrich the error with a type.
11981199
let kind = match m {
11991200
Some(Mutability::Mut) => "static mut",
12001201
Some(Mutability::Not) => "static",
12011202
None => "const",
12021203
};
1203-
let mut err = self.struct_span_err(id.span, &format!("missing type for `{kind}` item"));
1204+
1205+
let colon = match colon_present {
1206+
true => "",
1207+
false => ":",
1208+
};
1209+
1210+
let span = self.prev_token.span.shrink_to_hi();
1211+
let mut err = self.struct_span_err(span, &format!("missing type for `{kind}` item"));
12041212
err.span_suggestion(
1205-
id.span,
1213+
span,
12061214
"provide a type for the item",
1207-
format!("{id}: <type>"),
1215+
format!("{colon} <type>"),
12081216
Applicability::HasPlaceholders,
12091217
);
1210-
err.stash(id.span, StashKey::ItemNoType);
1218+
err.stash(span, StashKey::ItemNoType);
12111219

12121220
// The user intended that the type be inferred,
12131221
// so treat this as if the user wrote e.g. `const A: _ = expr;`.
1214-
P(Ty { kind: TyKind::Infer, span: id.span, id: ast::DUMMY_NODE_ID, tokens: None })
1222+
P(Ty { kind: TyKind::Infer, span, id: ast::DUMMY_NODE_ID, tokens: None })
12151223
}
12161224

12171225
/// Parses an enum declaration.

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1761,13 +1761,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17611761
.filter_map(|seg| seg.args.as_ref())
17621762
.flat_map(|a| a.args.iter())
17631763
{
1764-
if let hir::GenericArg::Type(hir_ty) = &arg {
1765-
let ty = self.resolve_vars_if_possible(
1766-
self.typeck_results.borrow().node_type(hir_ty.hir_id),
1767-
);
1768-
if ty == predicate.self_ty() {
1769-
error.obligation.cause.span = hir_ty.span;
1770-
}
1764+
if let hir::GenericArg::Type(hir_ty) = &arg
1765+
&& let Some(ty) =
1766+
self.typeck_results.borrow().node_type_opt(hir_ty.hir_id)
1767+
&& self.resolve_vars_if_possible(ty) == predicate.self_ty()
1768+
{
1769+
error.obligation.cause.span = hir_ty.span;
1770+
break;
17711771
}
17721772
}
17731773
}

compiler/rustc_typeck/src/check/pat.rs

+49-4
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
600600
// If there are multiple arms, make sure they all agree on
601601
// what the type of the binding `x` ought to be.
602602
if var_id != pat.hir_id {
603-
self.check_binding_alt_eq_ty(pat.span, var_id, local_ty, ti);
603+
self.check_binding_alt_eq_ty(ba, pat.span, var_id, local_ty, ti);
604604
}
605605

606606
if let Some(p) = sub {
@@ -610,7 +610,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
610610
local_ty
611611
}
612612

613-
fn check_binding_alt_eq_ty(&self, span: Span, var_id: HirId, ty: Ty<'tcx>, ti: TopInfo<'tcx>) {
613+
fn check_binding_alt_eq_ty(
614+
&self,
615+
ba: hir::BindingAnnotation,
616+
span: Span,
617+
var_id: HirId,
618+
ty: Ty<'tcx>,
619+
ti: TopInfo<'tcx>,
620+
) {
614621
let var_ty = self.local_ty(span, var_id).decl_ty;
615622
if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) {
616623
let hir = self.tcx.hir();
@@ -628,12 +635,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
628635
});
629636
let pre = if in_match { "in the same arm, " } else { "" };
630637
err.note(&format!("{}a binding must have the same type in all alternatives", pre));
631-
// FIXME: check if `var_ty` and `ty` can be made the same type by adding or removing
632-
// `ref` or `&` to the pattern.
638+
self.suggest_adding_missing_ref_or_removing_ref(
639+
&mut err,
640+
span,
641+
var_ty,
642+
self.resolve_vars_with_obligations(ty),
643+
ba,
644+
);
633645
err.emit();
634646
}
635647
}
636648

649+
fn suggest_adding_missing_ref_or_removing_ref(
650+
&self,
651+
err: &mut Diagnostic,
652+
span: Span,
653+
expected: Ty<'tcx>,
654+
actual: Ty<'tcx>,
655+
ba: hir::BindingAnnotation,
656+
) {
657+
match (expected.kind(), actual.kind(), ba) {
658+
(ty::Ref(_, inner_ty, _), _, hir::BindingAnnotation::Unannotated)
659+
if self.can_eq(self.param_env, *inner_ty, actual).is_ok() =>
660+
{
661+
err.span_suggestion_verbose(
662+
span.shrink_to_lo(),
663+
"consider adding `ref`",
664+
"ref ",
665+
Applicability::MaybeIncorrect,
666+
);
667+
}
668+
(_, ty::Ref(_, inner_ty, _), hir::BindingAnnotation::Ref)
669+
if self.can_eq(self.param_env, expected, *inner_ty).is_ok() =>
670+
{
671+
err.span_suggestion_verbose(
672+
span.with_hi(span.lo() + BytePos(4)),
673+
"consider removing `ref`",
674+
"",
675+
Applicability::MaybeIncorrect,
676+
);
677+
}
678+
_ => (),
679+
}
680+
}
681+
637682
// Precondition: pat is a Ref(_) pattern
638683
fn borrow_pat_suggestion(&self, err: &mut Diagnostic, pat: &Pat<'_>) {
639684
let tcx = self.tcx;

compiler/rustc_typeck/src/collect/type_of.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,9 @@ fn infer_placeholder_type<'a>(
801801
match tcx.sess.diagnostic().steal_diagnostic(span, StashKey::ItemNoType) {
802802
Some(mut err) => {
803803
if !ty.references_error() {
804+
// Only suggest adding `:` if it was missing (and suggested by parsing diagnostic)
805+
let colon = if span == item_ident.span.shrink_to_hi() { ":" } else { "" };
806+
804807
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
805808
// We are typeck and have the real type, so remove that and suggest the actual type.
806809
// FIXME(eddyb) this looks like it should be functionality on `Diagnostic`.
@@ -816,7 +819,7 @@ fn infer_placeholder_type<'a>(
816819
err.span_suggestion(
817820
span,
818821
&format!("provide a type for the {item}", item = kind),
819-
format!("{}: {}", item_ident, sugg_ty),
822+
format!("{colon} {sugg_ty}"),
820823
Applicability::MachineApplicable,
821824
);
822825
} else {

library/std/src/sys/solid/fs.rs

+12
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ pub struct OpenOptions {
7777
custom_flags: i32,
7878
}
7979

80+
#[derive(Copy, Clone, Debug, Default)]
81+
pub struct FileTimes {}
82+
8083
#[derive(Clone, PartialEq, Eq, Debug)]
8184
pub struct FilePermissions(c_short);
8285

@@ -126,6 +129,11 @@ impl FilePermissions {
126129
}
127130
}
128131

132+
impl FileTimes {
133+
pub fn set_accessed(&mut self, _t: SystemTime) {}
134+
pub fn set_modified(&mut self, _t: SystemTime) {}
135+
}
136+
129137
impl FileType {
130138
pub fn is_dir(&self) -> bool {
131139
self.is(abi::S_IFDIR)
@@ -452,6 +460,10 @@ impl File {
452460
pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
453461
unsupported()
454462
}
463+
464+
pub fn set_times(&self, _times: FileTimes) -> io::Result<()> {
465+
unsupported()
466+
}
455467
}
456468

457469
impl Drop for File {

0 commit comments

Comments
 (0)