Skip to content

Commit

Permalink
Auto merge of rust-lang#89414 - Manishearth:rollup-hs11bcq, r=Manishe…
Browse files Browse the repository at this point in the history
…arth

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
  • Loading branch information
bors committed Oct 1, 2021
2 parents 1c0ed0d + 9ea439d commit 598d89b
Show file tree
Hide file tree
Showing 30 changed files with 427 additions and 63 deletions.
17 changes: 9 additions & 8 deletions compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

Aggregate(ref kind, ref operands) => {
// active_field_index is for union initialization.
let (dest, active_field_index) = match **kind {
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
self.write_discriminant(variant_index, &dest)?;
if adt_def.is_enum() {
(self.place_downcast(&dest, variant_index)?, active_field_index)
assert!(active_field_index.is_none());
(self.place_downcast(&dest, variant_index)?, None)
} else {
if active_field_index.is_some() {
assert_eq!(operands.len(), 1);
}
(dest, active_field_index)
}
}
Expand All @@ -211,12 +216,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

for (i, operand) in operands.iter().enumerate() {
let op = self.eval_operand(operand, None)?;
// Ignore zero-sized fields.
if !op.layout.is_zst() {
let field_index = active_field_index.unwrap_or(i);
let field_dest = self.place_field(&dest, field_index)?;
self.copy_op(&op, &field_dest)?;
}
let field_index = active_field_index.unwrap_or(i);
let field_dest = self.place_field(&dest, field_index)?;
self.copy_op(&op, &field_dest)?;
}
}

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

Len(place) => {
// FIXME(CTFE): don't allow computing the length of arrays in const eval
let src = self.eval_place(place)?;
let mplace = self.force_allocation(&src)?;
let len = mplace.len(self)?;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ language_item_table! {
Oom, sym::oom, oom, Target::Fn, GenericRequirement::None;
AllocLayout, sym::alloc_layout, alloc_layout, Target::Struct, GenericRequirement::None;

Start, sym::start, start_fn, Target::Fn, GenericRequirement::None;
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);

EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;
Expand Down
55 changes: 36 additions & 19 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBu
struct_span_err!(sess, sp, E0004, "{}", &error_message)
}

#[derive(PartialEq)]
enum RefutableFlag {
Irrefutable,
Refutable,
}
use RefutableFlag::*;

struct MatchVisitor<'a, 'p, 'tcx> {
tcx: TyCtxt<'tcx>,
typeck_results: &'a ty::TypeckResults<'tcx>,
Expand Down Expand Up @@ -73,13 +80,13 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, '_, 'tcx> {
hir::LocalSource::AssignDesugar(_) => ("destructuring assignment binding", None),
};
self.check_irrefutable(&loc.pat, msg, sp);
self.check_patterns(&loc.pat);
self.check_patterns(&loc.pat, Irrefutable);
}

fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
intravisit::walk_param(self, param);
self.check_irrefutable(&param.pat, "function argument", None);
self.check_patterns(&param.pat);
self.check_patterns(&param.pat, Irrefutable);
}
}

Expand Down Expand Up @@ -113,9 +120,9 @@ impl PatCtxt<'_, '_> {
}

impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
fn check_patterns(&self, pat: &Pat<'_>) {
fn check_patterns(&self, pat: &Pat<'_>, rf: RefutableFlag) {
pat.walk_always(|pat| check_borrow_conflicts_in_at_patterns(self, pat));
check_for_bindings_named_same_as_variants(self, pat);
check_for_bindings_named_same_as_variants(self, pat, rf);
}

fn lower_pattern(
Expand Down Expand Up @@ -145,7 +152,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
}

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

for arm in arms {
// Check the arm for some things unrelated to exhaustiveness.
self.check_patterns(&arm.pat);
self.check_patterns(&arm.pat, Refutable);
if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
self.check_patterns(pat);
self.check_patterns(pat, Refutable);
let tpat = self.lower_pattern(&mut cx, pat, &mut false);
check_let_reachability(&mut cx, pat.hir_id, tpat, tpat.span());
}
Expand Down Expand Up @@ -297,7 +304,11 @@ fn const_not_var(
}
}

fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_, '_>, pat: &Pat<'_>) {
fn check_for_bindings_named_same_as_variants(
cx: &MatchVisitor<'_, '_, '_>,
pat: &Pat<'_>,
rf: RefutableFlag,
) {
pat.walk_always(|p| {
if let hir::PatKind::Binding(_, _, ident, None) = p.kind {
if let Some(ty::BindByValue(hir::Mutability::Not)) =
Expand All @@ -310,25 +321,31 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor<'_, '_, '_>, pat:
variant.ident == ident && variant.ctor_kind == CtorKind::Const
})
{
let variant_count = edef.variants.len();
cx.tcx.struct_span_lint_hir(
BINDINGS_WITH_VARIANT_NAME,
p.hir_id,
p.span,
|lint| {
let ty_path = cx.tcx.def_path_str(edef.did);
lint.build(&format!(
let mut err = lint.build(&format!(
"pattern binding `{}` is named the same as one \
of the variants of the type `{}`",
of the variants of the type `{}`",
ident, ty_path
))
.code(error_code!(E0170))
.span_suggestion(
p.span,
"to match on the variant, qualify the path",
format!("{}::{}", ty_path, ident),
Applicability::MachineApplicable,
)
.emit();
));
err.code(error_code!(E0170));
// If this is an irrefutable pattern, and there's > 1 variant,
// then we can't actually match on this. Applying the below
// suggestion would produce code that breaks on `check_irrefutable`.
if rf == Refutable || variant_count == 1 {
err.span_suggestion(
p.span,
"to match on the variant, qualify the path",
format!("{}::{}", ty_path, ident),
Applicability::MachineApplicable,
);
}
err.emit();
},
)
}
Expand Down
30 changes: 27 additions & 3 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl<'a> Resolver<'a> {
err.span_label(first_use_span, format!("first use of `{}`", name));
err
}
ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => {
let mut err = struct_span_err!(
self.session,
span,
Expand All @@ -208,9 +208,17 @@ impl<'a> Resolver<'a> {
trait_
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
method.span,
"there is an associated function with a similar name",
candidate.to_ident_string(),
Applicability::MaybeIncorrect,
);
}
err
}
ResolutionError::TypeNotMemberOfTrait(type_, trait_) => {
ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => {
let mut err = struct_span_err!(
self.session,
span,
Expand All @@ -220,9 +228,17 @@ impl<'a> Resolver<'a> {
trait_
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
type_.span,
"there is an associated type with a similar name",
candidate.to_ident_string(),
Applicability::MaybeIncorrect,
);
}
err
}
ResolutionError::ConstNotMemberOfTrait(const_, trait_) => {
ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => {
let mut err = struct_span_err!(
self.session,
span,
Expand All @@ -232,6 +248,14 @@ impl<'a> Resolver<'a> {
trait_
);
err.span_label(span, format!("not a member of trait `{}`", trait_));
if let Some(candidate) = candidate {
err.span_suggestion(
const_.span,
"there is an associated constant with a similar name",
candidate.to_ident_string(),
Applicability::MaybeIncorrect,
);
}
err
}
ResolutionError::VariableNotBoundInPattern(binding_error) => {
Expand Down
28 changes: 20 additions & 8 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1309,14 +1309,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
use crate::ResolutionError::*;
match &item.kind {
AssocItemKind::Const(_default, _ty, _expr) => {
debug!("resolve_implementation AssocItemKind::Const",);
debug!("resolve_implementation AssocItemKind::Const");
// If this is a trait impl, ensure the const
// exists in trait
this.check_trait_item(
item.ident,
&item.kind,
ValueNS,
item.span,
|n, s| ConstNotMemberOfTrait(n, s),
|i, s, c| ConstNotMemberOfTrait(i, s, c),
);

// We allow arbitrary const expressions inside of associated consts,
Expand All @@ -1338,6 +1339,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
);
}
AssocItemKind::Fn(box FnKind(.., generics, _)) => {
debug!("resolve_implementation AssocItemKind::Fn");
// We also need a new scope for the impl item type parameters.
this.with_generic_param_rib(
generics,
Expand All @@ -1347,9 +1349,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// exists in trait
this.check_trait_item(
item.ident,
&item.kind,
ValueNS,
item.span,
|n, s| MethodNotMemberOfTrait(n, s),
|i, s, c| MethodNotMemberOfTrait(i, s, c),
);

visit::walk_assoc_item(
Expand All @@ -1366,6 +1369,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
_,
_,
)) => {
debug!("resolve_implementation AssocItemKind::TyAlias");
// We also need a new scope for the impl item type parameters.
this.with_generic_param_rib(
generics,
Expand All @@ -1375,9 +1379,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// exists in trait
this.check_trait_item(
item.ident,
&item.kind,
TypeNS,
item.span,
|n, s| TypeNotMemberOfTrait(n, s),
|i, s, c| TypeNotMemberOfTrait(i, s, c),
);

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

fn check_trait_item<F>(&mut self, ident: Ident, ns: Namespace, span: Span, err: F)
where
F: FnOnce(Symbol, &str) -> ResolutionError<'_>,
fn check_trait_item<F>(
&mut self,
ident: Ident,
kind: &AssocItemKind,
ns: Namespace,
span: Span,
err: F,
) where
F: FnOnce(Ident, &str, Option<Symbol>) -> ResolutionError<'_>,
{
// If there is a TraitRef in scope for an impl, then the method must be in the
// trait.
Expand All @@ -1420,8 +1431,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
)
.is_err()
{
let candidate = self.find_similarly_named_assoc_item(ident.name, kind);
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
self.report_error(span, err(ident.name, &path_names_to_string(path)));
self.report_error(span, err(ident, &path_names_to_string(path), candidate));
}
}
}
Expand Down
38 changes: 36 additions & 2 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::{PathResult, PathSource, Segment};

use rustc_ast::visit::FnKind;
use rustc_ast::{
self as ast, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind, NodeId, Path, Ty,
TyKind,
self as ast, AssocItemKind, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind,
NodeId, Path, Ty, TyKind,
};
use rustc_ast_pretty::pprust::path_segment_to_string;
use rustc_data_structures::fx::FxHashSet;
Expand Down Expand Up @@ -1150,6 +1150,40 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
true
}

/// Given the target `ident` and `kind`, search for the similarly named associated item
/// in `self.current_trait_ref`.
crate fn find_similarly_named_assoc_item(
&mut self,
ident: Symbol,
kind: &AssocItemKind,
) -> Option<Symbol> {
let module = if let Some((module, _)) = self.current_trait_ref {
module
} else {
return None;
};
if ident == kw::Underscore {
// We do nothing for `_`.
return None;
}

let resolutions = self.r.resolutions(module);
let targets = resolutions
.borrow()
.iter()
.filter_map(|(key, res)| res.borrow().binding.map(|binding| (key, binding.res())))
.filter(|(_, res)| match (kind, res) {
(AssocItemKind::Const(..), Res::Def(DefKind::AssocConst, _)) => true,
(AssocItemKind::Fn(_), Res::Def(DefKind::AssocFn, _)) => true,
(AssocItemKind::TyAlias(..), Res::Def(DefKind::AssocTy, _)) => true,
_ => false,
})
.map(|(key, _)| key.ident.name)
.collect::<Vec<_>>();

find_best_match_for_name(&targets, ident, None)
}

fn lookup_assoc_candidate<FilterFn>(
&mut self,
ident: Ident,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,11 @@ enum ResolutionError<'a> {
/// parameter list.
NameAlreadyUsedInParameterList(Symbol, Span),
/// Error E0407: method is not a member of trait.
MethodNotMemberOfTrait(Symbol, &'a str),
MethodNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0437: type is not a member of trait.
TypeNotMemberOfTrait(Symbol, &'a str),
TypeNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0438: const is not a member of trait.
ConstNotMemberOfTrait(Symbol, &'a str),
ConstNotMemberOfTrait(Ident, &'a str, Option<Symbol>),
/// Error E0408: variable `{}` is not bound in all patterns.
VariableNotBoundInPattern(&'a BindingError),
/// Error E0409: variable `{}` is bound in inconsistent ways within the same match arm.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_typeck/src/check/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

let callee_ty = self.resolve_vars_if_possible(callee_ty);
let mut err = type_error_struct!(
self.tcx.sess,
callee_expr.span,
Expand Down
Loading

0 comments on commit 598d89b

Please sign in to comment.