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 9 pull requests #78386

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 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
cabf6d0
Tweak `if let` suggestion to be more liberal with suggestion and to n…
estebank Sep 28, 2020
955c0c3
Rollup merge of #74477 - chansuke:sys-wasm-unsafe-op-in-unsafe-fn, r=…
Dylan-DPC Oct 26, 2020
34d2351
Rollup merge of #77283 - estebank:if-let-sugg, r=Mark-Simulacrum
Dylan-DPC Oct 26, 2020
46f9f01
Rollup merge of #77836 - RalfJung:transmute_copy, r=Mark-Simulacrum
Dylan-DPC Oct 26, 2020
2d189aa
Rollup merge of #78137 - tmiasko:compiletest-tracing, r=Mark-Simulacrum
Dylan-DPC Oct 26, 2020
f6d182b
Rollup merge of #78161 - jonas-schievink:irlo-issue-link, r=Mark-Simu…
Dylan-DPC Oct 26, 2020
bfb4439
Rollup merge of #78214 - estebank:match-semicolon, r=oli-obk
Dylan-DPC Oct 26, 2020
6b28db3
Rollup merge of #78227 - SergioBenitez:test-stdout-threading, r=m-ou-se
Dylan-DPC Oct 26, 2020
40d4db3
Rollup merge of #78247 - simonvandel:fix-78192, r=oli-obk
Dylan-DPC Oct 26, 2020
e86664e
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