Skip to content

Commit 598d89b

Browse files
committed
Auto merge of rust-lang#89414 - Manishearth:rollup-hs11bcq, r=Manishearth
Rollup of 8 pull requests Successful merges: - rust-lang#88782 (Fix ICE when `start` lang item has wrong generics) - rust-lang#89202 (Resolve infered types when complaining about unexpected call type ) - rust-lang#89248 (Suggest similarly named associated items in trait impls) - rust-lang#89303 (Add `#[must_not_suspend]` to some types in std) - rust-lang#89306 (thread: implements available_concurrency on haiku) - rust-lang#89314 (fix(lint): don't suggest refutable patterns to "fix" irrefutable bind) - rust-lang#89370 (CTFE: tweak aggregate rvalue handling) - rust-lang#89392 (bootstrap: Update comment in config.library.toml.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 1c0ed0d + 9ea439d commit 598d89b

File tree

30 files changed

+427
-63
lines changed

30 files changed

+427
-63
lines changed

compiler/rustc_const_eval/src/interpret/step.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
197197
}
198198

199199
Aggregate(ref kind, ref operands) => {
200+
// active_field_index is for union initialization.
200201
let (dest, active_field_index) = match **kind {
201202
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
202203
self.write_discriminant(variant_index, &dest)?;
203204
if adt_def.is_enum() {
204-
(self.place_downcast(&dest, variant_index)?, active_field_index)
205+
assert!(active_field_index.is_none());
206+
(self.place_downcast(&dest, variant_index)?, None)
205207
} else {
208+
if active_field_index.is_some() {
209+
assert_eq!(operands.len(), 1);
210+
}
206211
(dest, active_field_index)
207212
}
208213
}
@@ -211,12 +216,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
211216

212217
for (i, operand) in operands.iter().enumerate() {
213218
let op = self.eval_operand(operand, None)?;
214-
// Ignore zero-sized fields.
215-
if !op.layout.is_zst() {
216-
let field_index = active_field_index.unwrap_or(i);
217-
let field_dest = self.place_field(&dest, field_index)?;
218-
self.copy_op(&op, &field_dest)?;
219-
}
219+
let field_index = active_field_index.unwrap_or(i);
220+
let field_dest = self.place_field(&dest, field_index)?;
221+
self.copy_op(&op, &field_dest)?;
220222
}
221223
}
222224

@@ -253,7 +255,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
253255
}
254256

255257
Len(place) => {
256-
// FIXME(CTFE): don't allow computing the length of arrays in const eval
257258
let src = self.eval_place(place)?;
258259
let mplace = self.force_allocation(&src)?;
259260
let len = mplace.len(self)?;

compiler/rustc_hir/src/lang_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ language_item_table! {
300300
Oom, sym::oom, oom, Target::Fn, GenericRequirement::None;
301301
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;
302302

303-
Start, sym::start, start_fn, Target::Fn, GenericRequirement::None;
303+
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);
304304

305305
EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
306306
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+36-19
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBu
3939
struct_span_err!(sess, sp, E0004, "{}", &error_message)
4040
}
4141

42+
#[derive(PartialEq)]
43+
enum RefutableFlag {
44+
Irrefutable,
45+
Refutable,
46+
}
47+
use RefutableFlag::*;
48+
4249
struct MatchVisitor<'a, 'p, 'tcx> {
4350
tcx: TyCtxt<'tcx>,
4451
typeck_results: &'a ty::TypeckResults<'tcx>,
@@ -73,13 +80,13 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
7380
hir::LocalSource::AssignDesugar(_) => ("destructuring assignment binding", None),
7481
};
7582
self.check_irrefutable(&loc.pat, msg, sp);
76-
self.check_patterns(&loc.pat);
83+
self.check_patterns(&loc.pat, Irrefutable);
7784
}
7885

7986
fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
8087
intravisit::walk_param(self, param);
8188
self.check_irrefutable(&param.pat, "function argument", None);
82-
self.check_patterns(&param.pat);
89+
self.check_patterns(&param.pat, Irrefutable);
8390
}
8491
}
8592

@@ -113,9 +120,9 @@ impl PatCtxt<'_, '_> {
113120
}
114121

115122
impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
116-
fn check_patterns(&self, pat: &Pat<'_>) {
123+
fn check_patterns(&self, pat: &Pat<'_>, rf: RefutableFlag) {
117124
pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
118-
check_for_bindings_named_same_as_variants(self, pat);
125+
check_for_bindings_named_same_as_variants(self, pat, rf);
119126
}
120127

121128
fn lower_pattern(
@@ -145,7 +152,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
145152
}
146153

147154
fn check_let(&mut self, pat: &'tcx hir::Pat<'tcx>, expr: &hir::Expr<'_>, span: Span) {
148-
self.check_patterns(pat);
155+
self.check_patterns(pat, Refutable);
149156
let mut cx = self.new_cx(expr.hir_id);
150157
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
151158
check_let_reachability(&mut cx, pat.hir_id, tpat, span);
@@ -161,9 +168,9 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
161168

162169
for arm in arms {
163170
// Check the arm for some things unrelated to exhaustiveness.
164-
self.check_patterns(&arm.pat);
171+
self.check_patterns(&arm.pat, Refutable);
165172
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
166-
self.check_patterns(pat);
173+
self.check_patterns(pat, Refutable);
167174
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
168175
check_let_reachability(&mut cx, pat.hir_id, tpat, tpat.span());
169176
}
@@ -297,7 +304,11 @@ fn const_not_var(
297304
}
298305
}
299306

300-
fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_, '_>, pat: &Pat<'_>) {
307+
fn check_for_bindings_named_same_as_variants(
308+
cx: &MatchVisitor<'_, '_, '_>,
309+
pat: &Pat<'_>,
310+
rf: RefutableFlag,
311+
) {
301312
pat.walk_always(|p| {
302313
if let hir::PatKind::Binding(_, _, ident, None) = p.kind {
303314
if let Some(ty::BindByValue(hir::Mutability::Not)) =
@@ -310,25 +321,31 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_, '_>, pat:
310321
variant.ident == ident && variant.ctor_kind == CtorKind::Const
311322
})
312323
{
324+
let variant_count = edef.variants.len();
313325
cx.tcx.struct_span_lint_hir(
314326
BINDINGS_WITH_VARIANT_NAME,
315327
p.hir_id,
316328
p.span,
317329
|lint| {
318330
let ty_path = cx.tcx.def_path_str(edef.did);
319-
lint.build(&format!(
331+
let mut err = lint.build(&format!(
320332
"pattern binding `{}` is named the same as one \
321-
of the variants of the type `{}`",
333+
of the variants of the type `{}`",
322334
ident, ty_path
323-
))
324-
.code(error_code!(E0170))
325-
.span_suggestion(
326-
p.span,
327-
"to match on the variant, qualify the path",
328-
format!("{}::{}", ty_path, ident),
329-
Applicability::MachineApplicable,
330-
)
331-
.emit();
335+
));
336+
err.code(error_code!(E0170));
337+
// If this is an irrefutable pattern, and there's > 1 variant,
338+
// then we can't actually match on this. Applying the below
339+
// suggestion would produce code that breaks on `check_irrefutable`.
340+
if rf == Refutable || variant_count == 1 {
341+
err.span_suggestion(
342+
p.span,
343+
"to match on the variant, qualify the path",
344+
format!("{}::{}", ty_path, ident),
345+
Applicability::MachineApplicable,
346+
);
347+
}
348+
err.emit();
332349
},
333350
)
334351
}

compiler/rustc_resolve/src/diagnostics.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ impl<'a> Resolver<'a> {
198198
err.span_label(first_use_span, format!("first use of `{}`", name));
199199
err
200200
}
201-
ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
201+
ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => {
202202
let mut err = struct_span_err!(
203203
self.session,
204204
span,
@@ -208,9 +208,17 @@ impl<'a> Resolver<'a> {
208208
trait_
209209
);
210210
err.span_label(span, format!("not a member of trait `{}`", trait_));
211+
if let Some(candidate) = candidate {
212+
err.span_suggestion(
213+
method.span,
214+
"there is an associated function with a similar name",
215+
candidate.to_ident_string(),
216+
Applicability::MaybeIncorrect,
217+
);
218+
}
211219
err
212220
}
213-
ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
221+
ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => {
214222
let mut err = struct_span_err!(
215223
self.session,
216224
span,
@@ -220,9 +228,17 @@ impl<'a> Resolver<'a> {
220228
trait_
221229
);
222230
err.span_label(span, format!("not a member of trait `{}`", trait_));
231+
if let Some(candidate) = candidate {
232+
err.span_suggestion(
233+
type_.span,
234+
"there is an associated type with a similar name",
235+
candidate.to_ident_string(),
236+
Applicability::MaybeIncorrect,
237+
);
238+
}
223239
err
224240
}
225-
ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
241+
ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => {
226242
let mut err = struct_span_err!(
227243
self.session,
228244
span,
@@ -232,6 +248,14 @@ impl<'a> Resolver<'a> {
232248
trait_
233249
);
234250
err.span_label(span, format!("not a member of trait `{}`", trait_));
251+
if let Some(candidate) = candidate {
252+
err.span_suggestion(
253+
const_.span,
254+
"there is an associated constant with a similar name",
255+
candidate.to_ident_string(),
256+
Applicability::MaybeIncorrect,
257+
);
258+
}
235259
err
236260
}
237261
ResolutionError::VariableNotBoundInPattern(binding_error) => {

compiler/rustc_resolve/src/late.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -1309,14 +1309,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13091309
use crate::ResolutionError::*;
13101310
match &item.kind {
13111311
AssocItemKind::Const(_default, _ty, _expr) => {
1312-
debug!("resolve_implementation AssocItemKind::Const",);
1312+
debug!("resolve_implementation AssocItemKind::Const");
13131313
// If this is a trait impl, ensure the const
13141314
// exists in trait
13151315
this.check_trait_item(
13161316
item.ident,
1317+
&item.kind,
13171318
ValueNS,
13181319
item.span,
1319-
|n, s| ConstNotMemberOfTrait(n, s),
1320+
|i, s, c| ConstNotMemberOfTrait(i, s, c),
13201321
);
13211322

13221323
// We allow arbitrary const expressions inside of associated consts,
@@ -1338,6 +1339,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13381339
);
13391340
}
13401341
AssocItemKind::Fn(box FnKind(.., generics, _)) => {
1342+
debug!("resolve_implementation AssocItemKind::Fn");
13411343
// We also need a new scope for the impl item type parameters.
13421344
this.with_generic_param_rib(
13431345
generics,
@@ -1347,9 +1349,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13471349
// exists in trait
13481350
this.check_trait_item(
13491351
item.ident,
1352+
&item.kind,
13501353
ValueNS,
13511354
item.span,
1352-
|n, s| MethodNotMemberOfTrait(n, s),
1355+
|i, s, c| MethodNotMemberOfTrait(i, s, c),
13531356
);
13541357

13551358
visit::walk_assoc_item(
@@ -1366,6 +1369,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13661369
_,
13671370
_,
13681371
)) => {
1372+
debug!("resolve_implementation AssocItemKind::TyAlias");
13691373
// We also need a new scope for the impl item type parameters.
13701374
this.with_generic_param_rib(
13711375
generics,
@@ -1375,9 +1379,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
13751379
// exists in trait
13761380
this.check_trait_item(
13771381
item.ident,
1382+
&item.kind,
13781383
TypeNS,
13791384
item.span,
1380-
|n, s| TypeNotMemberOfTrait(n, s),
1385+
|i, s, c| TypeNotMemberOfTrait(i, s, c),
13811386
);
13821387

13831388
visit::walk_assoc_item(
@@ -1401,9 +1406,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
14011406
});
14021407
}
14031408

1404-
fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
1405-
where
1406-
F: FnOnce(Symbol, &str) -> ResolutionError<'_>,
1409+
fn check_trait_item<F>(
1410+
&mut self,
1411+
ident: Ident,
1412+
kind: &AssocItemKind,
1413+
ns: Namespace,
1414+
span: Span,
1415+
err: F,
1416+
) where
1417+
F: FnOnce(Ident, &str, Option<Symbol>) -> ResolutionError<'_>,
14071418
{
14081419
// If there is a TraitRef in scope for an impl, then the method must be in the
14091420
// trait.
@@ -1420,8 +1431,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
14201431
)
14211432
.is_err()
14221433
{
1434+
let candidate = self.find_similarly_named_assoc_item(ident.name, kind);
14231435
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
1424-
self.report_error(span, err(ident.name, &path_names_to_string(path)));
1436+
self.report_error(span, err(ident, &path_names_to_string(path), candidate));
14251437
}
14261438
}
14271439
}

compiler/rustc_resolve/src/late/diagnostics.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use crate::{PathResult, PathSource, Segment};
77

88
use rustc_ast::visit::FnKind;
99
use rustc_ast::{
10-
self as ast, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind, NodeId, Path, Ty,
11-
TyKind,
10+
self as ast, AssocItemKind, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind,
11+
NodeId, Path, Ty, TyKind,
1212
};
1313
use rustc_ast_pretty::pprust::path_segment_to_string;
1414
use rustc_data_structures::fx::FxHashSet;
@@ -1150,6 +1150,40 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
11501150
true
11511151
}
11521152

1153+
/// Given the target `ident` and `kind`, search for the similarly named associated item
1154+
/// in `self.current_trait_ref`.
1155+
crate fn find_similarly_named_assoc_item(
1156+
&mut self,
1157+
ident: Symbol,
1158+
kind: &AssocItemKind,
1159+
) -> Option<Symbol> {
1160+
let module = if let Some((module, _)) = self.current_trait_ref {
1161+
module
1162+
} else {
1163+
return None;
1164+
};
1165+
if ident == kw::Underscore {
1166+
// We do nothing for `_`.
1167+
return None;
1168+
}
1169+
1170+
let resolutions = self.r.resolutions(module);
1171+
let targets = resolutions
1172+
.borrow()
1173+
.iter()
1174+
.filter_map(|(key, res)| res.borrow().binding.map(|binding| (key, binding.res())))
1175+
.filter(|(_, res)| match (kind, res) {
1176+
(AssocItemKind::Const(..), Res::Def(DefKind::AssocConst, _)) => true,
1177+
(AssocItemKind::Fn(_), Res::Def(DefKind::AssocFn, _)) => true,
1178+
(AssocItemKind::TyAlias(..), Res::Def(DefKind::AssocTy, _)) => true,
1179+
_ => false,
1180+
})
1181+
.map(|(key, _)| key.ident.name)
1182+
.collect::<Vec<_>>();
1183+
1184+
find_best_match_for_name(&targets, ident, None)
1185+
}
1186+
11531187
fn lookup_assoc_candidate<FilterFn>(
11541188
&mut self,
11551189
ident: Ident,

compiler/rustc_resolve/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ enum ResolutionError<'a> {
206206
/// parameter list.
207207
NameAlreadyUsedInParameterList(Symbol, Span),
208208
/// Error E0407: method is not a member of trait.
209-
MethodNotMemberOfTrait(Symbol, &'a str),
209+
MethodNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
210210
/// Error E0437: type is not a member of trait.
211-
TypeNotMemberOfTrait(Symbol, &'a str),
211+
TypeNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
212212
/// Error E0438: const is not a member of trait.
213-
ConstNotMemberOfTrait(Symbol, &'a str),
213+
ConstNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
214214
/// Error E0408: variable `{}` is not bound in all patterns.
215215
VariableNotBoundInPattern(&'a BindingError),
216216
/// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.

compiler/rustc_typeck/src/check/callee.rs

+1
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
356356
}
357357
}
358358

359+
let callee_ty = self.resolve_vars_if_possible(callee_ty);
359360
let mut err = type_error_struct!(
360361
self.tcx.sess,
361362
callee_expr.span,

0 commit comments

Comments
 (0)