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 10 pull requests #78383

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
95aac44
transmute_copy: explain that alignment is handled correctly
RalfJung Oct 11, 2020
08d5e96
Initialize tracing subscriber in compiletest tool
tmiasko Oct 20, 2020
2ec4d82
Add issue template link to IRLO
jonas-schievink Oct 20, 2020
95cbfb1
Retitle forum links
jonas-schievink Oct 20, 2020
57d01a9
Check which places are dead
simonvandel Oct 22, 2020
d0d0e78
Capture output from threads spawned in tests
tmandry Aug 5, 2020
db15596
Only load LOCAL_STREAMS if they are being used
SergioBenitez Oct 22, 2020
86df903
Tweak "use `.await`" suggestion
estebank Oct 21, 2020
a4ee3ca
Suggest semicolon removal on prior match arm
estebank Oct 22, 2020
671d7c4
Account for possible boxable `impl Future` in semicolon removal sugge…
estebank Oct 22, 2020
62ba365
Review comments: use newtype instead of `bool`
estebank Oct 22, 2020
3a0227b
Silence unnecessary `await foo?` knock-down error
estebank Oct 22, 2020
1829b4a
Add test case for different `impl Future`s
estebank Oct 22, 2020
c548511
Add more `.await` suggestions on E0308
estebank Oct 23, 2020
f5d7443
Suggest semicolon removal and boxing when appropriate
estebank Oct 23, 2020
d413bb6
`#[deny(unsafe_op_in_unsafe_fn)]` in sys/wasm
Jul 18, 2020
eed4510
Add some description for (malloc/calloc/free/realloc)
Oct 20, 2020
de87ae7
Add documents for DLMALLOC
Oct 24, 2020
d147f78
Fix unsafe operation of wasm32::memory_atomic_notify
Oct 24, 2020
d37b8cf
Remove unnecessary unsafe block from condvar_atomics & mutex_atomics
Oct 24, 2020
7b4c397
Do not try to report on closures to avoid ICE
JohnTitor Oct 23, 2020
4ec396e
Test with NLL explicitly
JohnTitor Oct 25, 2020
17a4c43
BTreeMap: move generic support functions out of navigate.rs
ssomers Oct 25, 2020
2df9277
BTreeMap: reuse NodeRef as Root, keep BoxedNode confined to edges
ssomers Oct 19, 2020
cabf6d0
Tweak `if let` suggestion to be more liberal with suggestion and to n…
estebank Sep 28, 2020
b2a2567
Rollup merge of #74477 - chansuke:sys-wasm-unsafe-op-in-unsafe-fn, r=…
Dylan-DPC Oct 26, 2020
b6fb183
Rollup merge of #77283 - estebank:if-let-sugg, r=Mark-Simulacrum
Dylan-DPC Oct 26, 2020
7c7f94b
Rollup merge of #77836 - RalfJung:transmute_copy, r=Mark-Simulacrum
Dylan-DPC Oct 26, 2020
f69c75f
Rollup merge of #78104 - ssomers:btree_root_redux, r=Mark-Simulacrum
Dylan-DPC Oct 26, 2020
0b1b1b5
Rollup merge of #78137 - tmiasko:compiletest-tracing, r=Mark-Simulacrum
Dylan-DPC Oct 26, 2020
d244fde
Rollup merge of #78161 - jonas-schievink:irlo-issue-link, r=Mark-Simu…
Dylan-DPC Oct 26, 2020
c27b862
Rollup merge of #78214 - estebank:match-semicolon, r=oli-obk
Dylan-DPC Oct 26, 2020
489c4b0
Rollup merge of #78227 - SergioBenitez:test-stdout-threading, r=m-ou-se
Dylan-DPC Oct 26, 2020
b829cef
Rollup merge of #78247 - simonvandel:fix-78192, r=oli-obk
Dylan-DPC Oct 26, 2020
2e741a8
Rollup merge of #78268 - JohnTitor:issue-78262, r=estebank
Dylan-DPC Oct 26, 2020
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
7 changes: 5 additions & 2 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Rust Programming Language Forum
- name: Question
url: https://users.rust-lang.org
about: Please ask and answer questions about Rust here.
about: Please ask and answer questions about Rust on the user forum.
- name: Feature Request
url: https://internals.rust-lang.org/
about: Please discuss language feature requests on the internals forum.
2 changes: 1 addition & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,6 @@ name = "compiletest"
version = "0.0.0"
dependencies = [
"diff",
"env_logger 0.7.1",
"getopts",
"glob",
"lazy_static",
Expand All @@ -660,6 +659,7 @@ dependencies = [
"serde",
"serde_json",
"tracing",
"tracing-subscriber",
"walkdir",
"winapi 0.3.9",
]
Expand Down
223 changes: 171 additions & 52 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ use super::region_constraints::GenericKind;
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};

use crate::infer;
use crate::infer::OriginalQueryValues;
use crate::traits::error_reporting::report_object_safety_error;
use crate::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
StatementAsExpression,
};

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
Expand All @@ -64,7 +64,6 @@ use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{Item, ItemKind, Node};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::ParamEnvAnd;
use rustc_middle::ty::{
self,
subst::{Subst, SubstsRef},
Expand Down Expand Up @@ -688,13 +687,36 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
};
let msg = "`match` arms have incompatible types";
err.span_label(outer_error_span, msg);
if let Some(sp) = semi_span {
err.span_suggestion_short(
sp,
"consider removing this semicolon",
String::new(),
Applicability::MachineApplicable,
);
if let Some((sp, boxed)) = semi_span {
if let (StatementAsExpression::NeedsBoxing, [.., prior_arm]) =
(boxed, &prior_arms[..])
{
err.multipart_suggestion(
"consider removing this semicolon and boxing the expressions",
vec![
(prior_arm.shrink_to_lo(), "Box::new(".to_string()),
(prior_arm.shrink_to_hi(), ")".to_string()),
(arm_span.shrink_to_lo(), "Box::new(".to_string()),
(arm_span.shrink_to_hi(), ")".to_string()),
(sp, String::new()),
],
Applicability::HasPlaceholders,
);
} else if matches!(boxed, StatementAsExpression::NeedsBoxing) {
err.span_suggestion_short(
sp,
"consider removing this semicolon and boxing the expressions",
String::new(),
Applicability::MachineApplicable,
);
} else {
err.span_suggestion_short(
sp,
"consider removing this semicolon",
String::new(),
Applicability::MachineApplicable,
);
}
}
if let Some(ret_sp) = opt_suggest_box_span {
// Get return type span and point to it.
Expand All @@ -717,13 +739,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if let Some(sp) = outer {
err.span_label(sp, "`if` and `else` have incompatible types");
}
if let Some(sp) = semicolon {
err.span_suggestion_short(
sp,
"consider removing this semicolon",
String::new(),
Applicability::MachineApplicable,
);
if let Some((sp, boxed)) = semicolon {
if matches!(boxed, StatementAsExpression::NeedsBoxing) {
err.multipart_suggestion(
"consider removing this semicolon and boxing the expression",
vec![
(then.shrink_to_lo(), "Box::new(".to_string()),
(then.shrink_to_hi(), ")".to_string()),
(else_sp.shrink_to_lo(), "Box::new(".to_string()),
(else_sp.shrink_to_hi(), ")".to_string()),
(sp, String::new()),
],
Applicability::MachineApplicable,
);
} else {
err.span_suggestion_short(
sp,
"consider removing this semicolon",
String::new(),
Applicability::MachineApplicable,
);
}
}
if let Some(ret_sp) = opt_suggest_box_span {
self.suggest_boxing_for_return_impl_trait(
Expand Down Expand Up @@ -1602,6 +1638,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
Mismatch::Variable(exp_found) => Some(exp_found),
Mismatch::Fixed(_) => None,
};
let exp_found = match terr {
// `terr` has more accurate type information than `exp_found` in match expressions.
ty::error::TypeError::Sorts(terr)
if exp_found.map_or(false, |ef| terr.found == ef.found) =>
{
Some(*terr)
}
_ => exp_found,
};
debug!("exp_found {:?} terr {:?}", exp_found, terr);
if let Some(exp_found) = exp_found {
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
self.suggest_await_on_expect_found(cause, span, &exp_found, diag);
Expand All @@ -1623,6 +1669,53 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.note_error_origin(diag, cause, exp_found);
}

fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
if let ty::Opaque(def_id, substs) = ty.kind() {
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
// Future::Output
let item_def_id = self
.tcx
.associated_items(future_trait)
.in_definition_order()
.next()
.unwrap()
.def_id;

let bounds = self.tcx.explicit_item_bounds(*def_id);

for (predicate, _) in bounds {
let predicate = predicate.subst(self.tcx, substs);
if let ty::PredicateAtom::Projection(projection_predicate) =
predicate.skip_binders()
{
if projection_predicate.projection_ty.item_def_id == item_def_id {
// We don't account for multiple `Future::Output = Ty` contraints.
return Some(projection_predicate.ty);
}
}
}
}
None
}

/// A possible error is to forget to add `.await` when using futures:
///
/// ```
/// async fn make_u32() -> u32 {
/// 22
/// }
///
/// fn take_u32(x: u32) {}
///
/// async fn foo() {
/// let x = make_u32();
/// take_u32(x);
/// }
/// ```
///
/// This routine checks if the found type `T` implements `Future<Output=U>` where `U` is the
/// expected type. If this is the case, and we are inside of an async body, it suggests adding
/// `.await` to the tail of the expression.
fn suggest_await_on_expect_found(
&self,
cause: &ObligationCause<'tcx>,
Expand All @@ -1632,50 +1725,76 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
) {
debug!(
"suggest_await_on_expect_found: exp_span={:?}, expected_ty={:?}, found_ty={:?}",
exp_span, exp_found.expected, exp_found.found
exp_span, exp_found.expected, exp_found.found,
);

if let ty::Opaque(def_id, _) = *exp_found.expected.kind() {
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
// Future::Output
let item_def_id = self
.tcx
.associated_items(future_trait)
.in_definition_order()
.next()
.unwrap()
.def_id;
if let ObligationCauseCode::CompareImplMethodObligation { .. } = &cause.code {
return;
}

let projection_ty = self.tcx.projection_ty_from_predicates((def_id, item_def_id));
if let Some(projection_ty) = projection_ty {
let projection_query = self.canonicalize_query(
&ParamEnvAnd { param_env: self.tcx.param_env(def_id), value: projection_ty },
&mut OriginalQueryValues::default(),
);
if let Ok(resp) = self.tcx.normalize_projection_ty(projection_query) {
let normalized_ty = resp.value.value.normalized_ty;
debug!("suggest_await_on_expect_found: normalized={:?}", normalized_ty);
if ty::TyS::same_type(normalized_ty, exp_found.found) {
let span = if let ObligationCauseCode::Pattern {
span,
origin_expr: _,
root_ty: _,
} = cause.code
{
// scrutinee's span
span.unwrap_or(exp_span)
} else {
exp_span
};
diag.span_suggestion_verbose(
span.shrink_to_hi(),
"consider awaiting on the future",
".await".to_string(),
match (
self.get_impl_future_output_ty(exp_found.expected),
self.get_impl_future_output_ty(exp_found.found),
) {
(Some(exp), Some(found)) if ty::TyS::same_type(exp, found) => match &cause.code {
ObligationCauseCode::IfExpression(box IfExpressionCause { then, .. }) => {
diag.multipart_suggestion(
"consider `await`ing on both `Future`s",
vec![
(then.shrink_to_hi(), ".await".to_string()),
(exp_span.shrink_to_hi(), ".await".to_string()),
],
Applicability::MaybeIncorrect,
);
}
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
prior_arms,
..
}) => {
if let [.., arm_span] = &prior_arms[..] {
diag.multipart_suggestion(
"consider `await`ing on both `Future`s",
vec![
(arm_span.shrink_to_hi(), ".await".to_string()),
(exp_span.shrink_to_hi(), ".await".to_string()),
],
Applicability::MaybeIncorrect,
);
} else {
diag.help("consider `await`ing on both `Future`s");
}
}
_ => {
diag.help("consider `await`ing on both `Future`s");
}
},
(_, Some(ty)) if ty::TyS::same_type(exp_found.expected, ty) => {
let span = match cause.code {
// scrutinee's span
ObligationCauseCode::Pattern { span: Some(span), .. } => span,
_ => exp_span,
};
diag.span_suggestion_verbose(
span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await".to_string(),
Applicability::MaybeIncorrect,
);
}
(Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => {
let span = match cause.code {
// scrutinee's span
ObligationCauseCode::Pattern { span: Some(span), .. } => span,
_ => exp_span,
};
diag.span_suggestion_verbose(
span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await".to_string(),
Applicability::MaybeIncorrect,
);
}
_ => {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
) if **sub_r == RegionKind::ReStatic => {
// This is for an implicit `'static` requirement coming from `impl dyn Trait {}`.
if let ObligationCauseCode::UnifyReceiver(ctxt) = &cause.code {
// This may have a closure and it would cause ICE
// through `find_param_with_region` (#78262).
let anon_reg_sup = tcx.is_suitable_region(sup_r)?;
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
if fn_returns.is_empty() {
return None;
}

let param = self.find_param_with_region(sup_r, sub_r)?;
let lifetime = if sup_r.has_name() {
format!("lifetime `{}`", sup_r)
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ impl Write for Sink {
Ok(())
}
}
impl io::LocalOutput for Sink {
fn clone_box(&self) -> Box<dyn io::LocalOutput> {
Box::new(Self(self.0.clone()))
}
}

/// Like a `thread::Builder::spawn` followed by a `join()`, but avoids the need
/// for `'static` bounds.
Expand Down
17 changes: 15 additions & 2 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,11 +340,24 @@ impl ObligationCauseCode<'_> {
#[cfg(target_arch = "x86_64")]
static_assert_size!(ObligationCauseCode<'_>, 32);

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum StatementAsExpression {
CorrectType,
NeedsBoxing,
}

impl<'tcx> ty::Lift<'tcx> for StatementAsExpression {
type Lifted = StatementAsExpression;
fn lift_to_tcx(self, _tcx: TyCtxt<'tcx>) -> Option<StatementAsExpression> {
Some(self)
}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
pub struct MatchExpressionArmCause<'tcx> {
pub arm_span: Span,
pub scrut_span: Span,
pub semi_span: Option<Span>,
pub semi_span: Option<(Span, StatementAsExpression)>,
pub source: hir::MatchSource,
pub prior_arms: Vec<Span>,
pub last_ty: Ty<'tcx>,
Expand All @@ -357,7 +370,7 @@ pub struct IfExpressionCause {
pub then: Span,
pub else_sp: Span,
pub outer: Option<Span>,
pub semicolon: Option<Span>,
pub semicolon: Option<(Span, StatementAsExpression)>,
pub opt_suggest_box_span: Option<Span>,
}

Expand Down
Loading