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 #72251

Merged
merged 33 commits into from
May 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
bdfdc71
Implement FromStr for OsString
glandium Apr 29, 2020
cf5e4a7
Add explicit references to the BuildHasher trait
Mark-Simulacrum Apr 29, 2020
d80ac14
Extend rustdoc-js tester to allow to test multiple queries in one file
GuillaumeGomez Apr 30, 2020
7590c39
Improve doc alias JS code
GuillaumeGomez Apr 30, 2020
cf41b1d
Improve doc alias discovery
GuillaumeGomez Apr 30, 2020
3a0727e
Add more tests for doc aliases
GuillaumeGomez Apr 30, 2020
9697c46
Update std tests
GuillaumeGomez Apr 30, 2020
f581cf7
Merge aliases and search-index
GuillaumeGomez May 4, 2020
32a46e9
add test case for issue-61076
csmoe May 6, 2020
2e2aac4
add try trait as lang item
csmoe May 6, 2020
114cd00
normalize Future::Ouput
csmoe May 9, 2020
627f473
suggest await before try when performing trait selection
csmoe May 10, 2020
c7e64f5
remove try_trait lang item
csmoe May 10, 2020
23d880b
rustc_driver: factor out computing the exit code
RalfJung May 10, 2020
51e466d
rustc_driver::main: more informative return type
RalfJung May 10, 2020
a1104b4
bless ui tests
csmoe May 10, 2020
883c177
Move doc alias discovery into the Attributes struct and some code imp…
GuillaumeGomez May 4, 2020
c4d9318
Make current crate aliases go first
GuillaumeGomez May 7, 2020
e17ac66
* Update aliases data struct from HashMap to BTreeMap to have more de…
GuillaumeGomez May 13, 2020
0dc74dc
cleanup stale FIXME(#64197)
sergey-melnychuk May 14, 2020
8954379
make sure even unleashed miri does not do pointer stuff
RalfJung May 14, 2020
e84b379
[const-prop] Don't replace Rvalues that are already constants
wesleywiser Apr 23, 2020
257e377
doc: add links to rotate_(left|right)
tesuji May 15, 2020
10d7da4
implement type_implments_trait query
csmoe May 14, 2020
86f48c5
Rollup merge of #71662 - glandium:osstring_from_str, r=sfackler
Dylan-DPC May 16, 2020
21d58a1
Rollup merge of #71677 - Mark-Simulacrum:hasher-docs, r=Amanieu
Dylan-DPC May 16, 2020
154db50
Rollup merge of #71724 - GuillaumeGomez:doc-alias-improvements, r=oll…
Dylan-DPC May 16, 2020
badcf26
Rollup merge of #71948 - csmoe:issue-61076, r=oli-obk
Dylan-DPC May 16, 2020
040e242
Rollup merge of #72090 - RalfJung:rustc_driver-exit-code, r=oli-obk
Dylan-DPC May 16, 2020
c1d5640
Rollup merge of #72206 - sergey-melnychuk:cleanup-stale-fixme, r=petr…
Dylan-DPC May 16, 2020
89866ce
Rollup merge of #72218 - RalfJung:test-unleashed-ptrs, r=oli-obk
Dylan-DPC May 16, 2020
941dfb9
Rollup merge of #72220 - wesleywiser:const_prop_eval_consts, r=oli-obk
Dylan-DPC May 16, 2020
a27b1b6
Rollup merge of #72224 - lzutao:links, r=Dylan-DPC
Dylan-DPC May 16, 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
16 changes: 8 additions & 8 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1499,8 +1499,8 @@ any high-order bits of `rhs` that would cause the shift to exceed the bitwidth o

Note that this is *not* the same as a rotate-left; the RHS of a wrapping shift-left is restricted to
the range of the type, rather than the bits shifted out of the LHS being returned to the other end.
The primitive integer types all implement a `rotate_left` function, which may be what you want
instead.
The primitive integer types all implement a `[`rotate_left`](#method.rotate_left) function,
which may be what you want instead.

# Examples

Expand Down Expand Up @@ -1531,8 +1531,8 @@ removes any high-order bits of `rhs` that would cause the shift to exceed the bi

Note that this is *not* the same as a rotate-right; the RHS of a wrapping shift-right is restricted
to the range of the type, rather than the bits shifted out of the LHS being returned to the other
end. The primitive integer types all implement a `rotate_right` function, which may be what you want
instead.
end. The primitive integer types all implement a [`rotate_right`](#method.rotate_right) function,
which may be what you want instead.

# Examples

Expand Down Expand Up @@ -3610,8 +3610,8 @@ Note that this is *not* the same as a rotate-left; the
RHS of a wrapping shift-left is restricted to the range
of the type, rather than the bits shifted out of the LHS
being returned to the other end. The primitive integer
types all implement a `rotate_left` function, which may
be what you want instead.
types all implement a [`rotate_left`](#method.rotate_left) function,
which may be what you want instead.

# Examples

Expand Down Expand Up @@ -3644,8 +3644,8 @@ Note that this is *not* the same as a rotate-right; the
RHS of a wrapping shift-right is restricted to the range
of the type, rather than the bits shifted out of the LHS
being returned to the other end. The primitive integer
types all implement a `rotate_right` function, which may
be what you want instead.
types all implement a [`rotate_right`](#method.rotate_right) function,
which may be what you want instead.

# Examples

Expand Down
23 changes: 14 additions & 9 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,16 @@ pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorReported>
})
}

/// Variant of `catch_fatal_errors` for the `interface::Result` return type
/// that also computes the exit code.
pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
let result = catch_fatal_errors(f).and_then(|result| result);
match result {
Ok(()) => EXIT_SUCCESS,
Err(_) => EXIT_FAILURE,
}
}

lazy_static! {
static ref DEFAULT_HOOK: Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static> = {
let hook = panic::take_hook();
Expand Down Expand Up @@ -1228,12 +1238,12 @@ pub fn init_rustc_env_logger() {
env_logger::init_from_env("RUSTC_LOG");
}

pub fn main() {
pub fn main() -> ! {
let start = Instant::now();
init_rustc_env_logger();
let mut callbacks = TimePassesCallbacks::default();
install_ice_hook();
let result = catch_fatal_errors(|| {
let exit_code = catch_with_exit_code(|| {
let args = env::args_os()
.enumerate()
.map(|(i, arg)| {
Expand All @@ -1246,13 +1256,8 @@ pub fn main() {
})
.collect::<Vec<_>>();
run_compiler(&args, &mut callbacks, None, None)
})
.and_then(|result| result);
let exit_code = match result {
Ok(_) => EXIT_SUCCESS,
Err(_) => EXIT_FAILURE,
};
});
// The extra `\t` is necessary to align this label with the others.
print_time_passes_entry(callbacks.time_passes, "\ttotal", start.elapsed());
process::exit(exit_code);
process::exit(exit_code)
}
4 changes: 2 additions & 2 deletions src/librustc_expand/parse/lexer/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ fn t1() {
assert_eq!(string_reader.next_token(), token::Whitespace);
// Read another token.
let tok3 = string_reader.next_token();
assert_eq!(string_reader.pos.clone(), BytePos(28));
assert_eq!(string_reader.pos(), BytePos(28));
let tok4 = Token::new(mk_ident("main"), Span::with_root_ctxt(BytePos(24), BytePos(28)));
assert_eq!(tok3.kind, tok4.kind);
assert_eq!(tok3.span, tok4.span);

assert_eq!(string_reader.next_token(), token::OpenDelim(token::Paren));
assert_eq!(string_reader.pos.clone(), BytePos(29))
assert_eq!(string_reader.pos(), BytePos(29))
})
}

Expand Down
6 changes: 1 addition & 5 deletions src/librustc_middle/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,11 +390,7 @@ impl<'hir> Map<'hir> {
/// Given a `HirId`, returns the `BodyId` associated with it,
/// if the node is a body owner, otherwise returns `None`.
pub fn maybe_body_owned_by(&self, hir_id: HirId) -> Option<BodyId> {
if let Some(node) = self.find(hir_id) {
associated_body(node)
} else {
bug!("no entry for id `{}`", hir_id)
}
self.find(hir_id).map(associated_body).flatten()
}

/// Given a body owner's id, returns the `BodyId` associated with it.
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_middle/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1164,6 +1164,12 @@ rustc_queries! {
desc { "evaluating trait selection obligation `{}`", goal.value }
}

query type_implements_trait(
key: (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>, )
) -> bool {
desc { "evaluating `type_implements_trait` `{:?}`", key }
}

/// Do not call this query directly: part of the `Eq` type-op
query type_op_ascribe_user_type(
goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx>
Expand Down
12 changes: 12 additions & 0 deletions src/librustc_middle/ty/query/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,15 @@ impl Key for (Symbol, u32, u32) {
DUMMY_SP
}
}

impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) {
type CacheSelector = DefaultCacheSelector;

fn query_crate(&self) -> CrateNum {
LOCAL_CRATE
}

fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
DUMMY_SP
}
}
7 changes: 7 additions & 0 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
value: OpTy<'tcx>,
source_info: SourceInfo,
) {
if let Rvalue::Use(Operand::Constant(c)) = rval {
if !matches!(c.literal.val, ConstKind::Unevaluated(..)) {
trace!("skipping replace of Rvalue::Use({:?} because it is already a const", c);
return;
}
}

trace!("attepting to replace {:?} with {:?}", rval, value);
if let Err(e) = self.ecx.const_validate_operand(
value,
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_parse/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ pub struct StringReader<'a> {
/// Initial position, read-only.
start_pos: BytePos,
/// The absolute offset within the source_map of the current character.
// FIXME(#64197): `pub` is needed by tests for now.
pub pos: BytePos,
pos: BytePos,
/// Stop reading src at this index.
end_src_index: usize,
/// Source text to tokenize.
Expand Down Expand Up @@ -436,6 +435,10 @@ impl<'a> StringReader<'a> {
}
}

pub fn pos(&self) -> BytePos {
self.pos
}

#[inline]
fn src_index(&self, pos: BytePos) -> usize {
(pos - self.start_pos).to_usize()
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trait_selection/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
self.note_version_mismatch(&mut err, &trait_ref);
self.suggest_await_before_try(&mut err, &obligation, &trait_ref, span);
if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) {
err.emit();
return;
Expand Down
101 changes: 101 additions & 0 deletions src/librustc_trait_selection/traits/error_reporting/suggestions.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use super::{
EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
SelectionContext,
};

use crate::infer::InferCtxt;
use crate::traits::normalize_projection_type;

use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items;
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
use rustc_middle::ty::TypeckTables;
use rustc_middle::ty::{
Expand Down Expand Up @@ -150,6 +153,15 @@ pub trait InferCtxtExt<'tcx> {
T: fmt::Display;

fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>);

/// Suggest to await before try: future? => future.await?
fn suggest_await_before_try(
&self,
err: &mut DiagnosticBuilder<'_>,
obligation: &PredicateObligation<'tcx>,
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
span: Span,
);
}

fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
Expand Down Expand Up @@ -1822,6 +1834,95 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
suggested_limit, self.tcx.crate_name,
));
}

fn suggest_await_before_try(
&self,
err: &mut DiagnosticBuilder<'_>,
obligation: &PredicateObligation<'tcx>,
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
span: Span,
) {
debug!(
"suggest_await_befor_try: obligation={:?}, span={:?}, trait_ref={:?}, trait_ref_self_ty={:?}",
obligation,
span,
trait_ref,
trait_ref.self_ty()
);
let body_hir_id = obligation.cause.body_id;
let item_id = self.tcx.hir().get_parent_node(body_hir_id);

if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(item_id) {
let body = self.tcx.hir().body(body_id);
if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
let future_trait =
self.tcx.require_lang_item(lang_items::FutureTraitLangItem, None);

let self_ty = self.resolve_vars_if_possible(&trait_ref.self_ty());

let impls_future = self.tcx.type_implements_trait((
future_trait,
self_ty,
ty::List::empty(),
obligation.param_env,
));

let item_def_id = self
.tcx
.associated_items(future_trait)
.in_definition_order()
.next()
.unwrap()
.def_id;
// `<T as Future>::Output`
let projection_ty = ty::ProjectionTy {
// `T`
substs: self.tcx.mk_substs_trait(
trait_ref.self_ty(),
self.fresh_substs_for_item(span, item_def_id),
),
// `Future::Output`
item_def_id,
};

let mut selcx = SelectionContext::new(self);

let mut obligations = vec![];
let normalized_ty = normalize_projection_type(
&mut selcx,
obligation.param_env,
projection_ty,
obligation.cause.clone(),
0,
&mut obligations,
);

debug!(
"suggest_await_befor_try: normalized_projection_type {:?}",
self.resolve_vars_if_possible(&normalized_ty)
);
let try_obligation = self.mk_obligation_for_def_id(
trait_ref.def_id(),
normalized_ty,
obligation.cause.clone(),
obligation.param_env,
);
debug!("suggest_await_befor_try: try_trait_obligation {:?}", try_obligation);
if self.predicate_may_hold(&try_obligation) && impls_future {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
if snippet.ends_with('?') {
err.span_suggestion(
span,
"consider using `.await` here",
format!("{}.await?", snippet.trim_end_matches('?')),
Applicability::MaybeIncorrect,
);
}
}
}
}
}
}
}

/// Collect all the returned expressions within the input expression.
Expand Down
42 changes: 41 additions & 1 deletion src/librustc_trait_selection/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ use rustc_hir::def_id::DefId;
use rustc_middle::middle::region;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, WithConstness};
use rustc_middle::ty::{
self, GenericParamDefKind, ParamEnv, ToPredicate, Ty, TyCtxt, WithConstness,
};
use rustc_span::Span;

use std::fmt::Debug;
Expand Down Expand Up @@ -523,6 +525,43 @@ fn vtable_methods<'tcx>(
}))
}

/// Check whether a `ty` implements given trait(trait_def_id).
///
/// NOTE: Always return `false` for a type which needs inference.
fn type_implements_trait<'tcx>(
tcx: TyCtxt<'tcx>,
key: (
DefId, // trait_def_id,
Ty<'tcx>, // type
SubstsRef<'tcx>,
ParamEnv<'tcx>,
),
) -> bool {
let (trait_def_id, ty, params, param_env) = key;

debug!(
"type_implements_trait: trait_def_id={:?}, type={:?}, params={:?}, param_env={:?}",
trait_def_id, ty, params, param_env
);

// Do not check on infer_types to avoid panic in evaluate_obligation.
if ty.has_infer_types() {
return false;
}

let ty = tcx.erase_regions(&ty);

let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, params) };

let obligation = Obligation {
cause: ObligationCause::dummy(),
param_env,
recursion_depth: 0,
predicate: trait_ref.without_const().to_predicate(),
};
tcx.infer_ctxt().enter(|infcx| infcx.predicate_must_hold_modulo_regions(&obligation))
}

pub fn provide(providers: &mut ty::query::Providers<'_>) {
object_safety::provide(providers);
*providers = ty::query::Providers {
Expand All @@ -531,6 +570,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
vtable_methods,
substitute_normalize_and_test_predicates,
type_implements_trait,
..*providers
};
}
Loading