Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #107727

Merged
merged 16 commits into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/parse.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,9 @@ parse_unexpected_token_after_struct_name_found_other = expected `where`, `{"{"}`
parse_unexpected_self_in_generic_parameters = unexpected keyword `Self` in generic parameters
.note = you cannot use `Self` as a generic parameter because it is reserved for associated items

parse_unexpected_default_value_for_lifetime_in_generic_parameters = unexpected default lifetime parameter
.label = lifetime parameters cannot have default values

parse_multiple_where_clauses = cannot define duplicate `where` clauses on an item
.label = previous `where` clause starts here
.suggestion = consider joining the two `where` clauses into one
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|| self.suggest_clone_for_ref(err, expr, expr_ty, expected)
|| self.suggest_into(err, expr, expr_ty, expected)
|| self.suggest_floating_point_literal(err, expr, expected)
|| self.suggest_null_ptr_for_literal_zero_given_to_ptr_arg(err, expr, expected)
|| self.note_result_coercion(err, expr, expected, expr_ty);
if !suggested {
self.point_at_expr_source_of_inferred_type(err, expr, expr_ty, expected, expr.span);
Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: hir::ImplItemKind::Fn(ref sig, ..),
..
}) => Some((&sig.decl, ident, false)),
Node::Expr(&hir::Expr {
hir_id,
kind: hir::ExprKind::Closure(..),
..
}) if let Some(Node::Expr(&hir::Expr {
hir_id,
kind: hir::ExprKind::Call(..),
..
})) = self.tcx.hir().find_parent(hir_id) &&
let Some(Node::Item(&hir::Item {
ident,
kind: hir::ItemKind::Fn(ref sig, ..),
..
})) = self.tcx.hir().find_parent(hir_id) => {
Some((&sig.decl, ident, ident.name != sym::main))
},
_ => None,
}
}
Expand Down
74 changes: 73 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_hir::{
use rustc_hir_analysis::astconv::AstConv;
use rustc_infer::traits::{self, StatementAsExpression};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{
self, suggest_constraining_type_params, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty,
TypeVisitable,
Expand Down Expand Up @@ -704,10 +705,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
hir::FnRetTy::Return(ty) => {
let span = ty.span;

if let hir::TyKind::OpaqueDef(item_id, ..) = ty.kind
&& let hir::Node::Item(hir::Item {
kind: hir::ItemKind::OpaqueTy(op_ty),
..
}) = self.tcx.hir().get(item_id.hir_id())
&& let hir::OpaqueTy {
bounds: [bound], ..
} = op_ty
&& let hir::GenericBound::LangItemTrait(
hir::LangItem::Future, _, _, generic_args) = bound
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
&& let hir::TypeBinding { kind, .. } = ty_binding
&& let hir::TypeBindingKind::Equality { term } = kind
&& let hir::Term::Ty(term_ty) = term {
// Check if async function's return type was omitted.
// Don't emit suggestions if the found type is `impl Future<...>`.
debug!("suggest_missing_return_type: found = {:?}", found);
if found.is_suggestable(self.tcx, false) {
if term_ty.span.is_empty() {
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() });
return true;
} else {
err.subdiagnostic(ExpectedReturnTypeLabel::Other { span, expected });
}
}
}

// Only point to return type if the expected type is the return type, as if they
// are not, the expectation must have been caused by something else.
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
let span = ty.span;
let ty = self.astconv().ast_ty_to_ty(ty);
debug!("suggest_missing_return_type: return type {:?}", ty);
debug!("suggest_missing_return_type: expected type {:?}", ty);
Expand Down Expand Up @@ -1244,6 +1273,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

/// Suggest providing `std::ptr::null()` or `std::ptr::null_mut()` if they
/// pass in a literal 0 to an raw pointer.
#[instrument(skip(self, err))]
pub(crate) fn suggest_null_ptr_for_literal_zero_given_to_ptr_arg(
&self,
err: &mut Diagnostic,
expr: &hir::Expr<'_>,
expected_ty: Ty<'tcx>,
) -> bool {
// Expected type needs to be a raw pointer.
let ty::RawPtr(ty::TypeAndMut { mutbl, .. }) = expected_ty.kind() else {
return false;
};

// Provided expression needs to be a literal `0`.
let ExprKind::Lit(Spanned {
node: rustc_ast::LitKind::Int(0, _),
span,
}) = expr.kind else {
return false;
};

// We need to find a null pointer symbol to suggest
let null_sym = match mutbl {
hir::Mutability::Not => sym::ptr_null,
hir::Mutability::Mut => sym::ptr_null_mut,
};
let Some(null_did) = self.tcx.get_diagnostic_item(null_sym) else {
return false;
};
let null_path_str = with_no_trimmed_paths!(self.tcx.def_path_str(null_did));

// We have satisfied all requirements to provide a suggestion. Emit it.
err.span_suggestion(
span,
format!("if you meant to create a null pointer, use `{null_path_str}()`"),
null_path_str + "()",
Applicability::MachineApplicable,
);

true
}

pub(crate) fn suggest_associated_const(
&self,
err: &mut Diagnostic,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_dataflow/src/value_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ impl<V, T> TryFrom<ProjectionElem<V, T>> for TrackElem {
}

/// Invokes `f` on all direct fields of `ty`.
fn iter_fields<'tcx>(
pub fn iter_fields<'tcx>(
ty: Ty<'tcx>,
tcx: TyCtxt<'tcx>,
mut f: impl FnMut(Option<VariantIdx>, Field, Ty<'tcx>),
Expand Down Expand Up @@ -824,7 +824,7 @@ fn iter_fields<'tcx>(
}

/// Returns all locals with projections that have their reference or address taken.
fn excluded_locals(body: &Body<'_>) -> IndexVec<Local, bool> {
pub fn excluded_locals(body: &Body<'_>) -> IndexVec<Local, bool> {
struct Collector {
result: IndexVec<Local, bool>,
}
Expand Down
Loading