Auto merge of #73206 - Dylan-DPC:rollup-rha9g8q, r=Dylan-DPC

Rollup of 9 pull requests

Successful merges:

 - #72706 (Add windows group to triagebot)
 - #72789 (resolve: Do not suggest imports from the same module in which we are resolving)
 - #72890 (improper ctypes: normalize return types and transparent structs)
 - #72897 (normalize adt fields during structural match checking)
 - #73005 (Don't create impl candidates when obligation contains errors)
 - #73023 (Remove noisy suggestion of hash_map )
 - #73070 (Add regression test for const generic ICE in #72819)
 - #73157 (Don't lose empty `where` clause when pretty-printing)
 - #73184 (Reoder order in which MinGW libs are linked to fix recent breakage)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-06-10 22:01:37 +00:00
commit ec42485ee9
35 changed files with 350 additions and 315 deletions

View File

@ -362,7 +362,11 @@ impl Default for Generics {
fn default() -> Generics {
Generics {
params: Vec::new(),
where_clause: WhereClause { predicates: Vec::new(), span: DUMMY_SP },
where_clause: WhereClause {
has_where_token: false,
predicates: Vec::new(),
span: DUMMY_SP,
},
span: DUMMY_SP,
}
}
@ -371,6 +375,11 @@ fn default() -> Generics {
/// A where-clause in a definition.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct WhereClause {
/// `true` if we ate a `where` token: this can happen
/// if we parsed no predicates (e.g. `struct Foo where {}
/// This allows us to accurately pretty-print
/// in `nt_to_tokenstream`
pub has_where_token: bool,
pub predicates: Vec<WherePredicate>,
pub span: Span,
}

View File

@ -786,7 +786,7 @@ pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T)
}
pub fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) {
let WhereClause { predicates, span } = wc;
let WhereClause { has_where_token: _, predicates, span } = wc;
visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
vis.visit_span(span);
}

View File

@ -2593,7 +2593,7 @@ pub fn print_type_bounds(&mut self, prefix: &'static str, bounds: &[ast::Generic
}
crate fn print_where_clause(&mut self, where_clause: &ast::WhereClause) {
if where_clause.predicates.is_empty() {
if where_clause.predicates.is_empty() && !where_clause.has_where_token {
return;
}
@ -2739,7 +2739,11 @@ pub fn print_mutability(&mut self, mutbl: ast::Mutability, print_const: bool) {
}
let generics = ast::Generics {
params: Vec::new(),
where_clause: ast::WhereClause { predicates: Vec::new(), span: rustc_span::DUMMY_SP },
where_clause: ast::WhereClause {
has_where_token: false,
predicates: Vec::new(),
span: rustc_span::DUMMY_SP,
},
span: rustc_span::DUMMY_SP,
};
let header = ast::FnHeader { unsafety, ext, ..ast::FnHeader::default() };

View File

@ -216,7 +216,11 @@ fn mk_ty_param(
}
fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
Generics { params, where_clause: ast::WhereClause { predicates: Vec::new(), span }, span }
Generics {
params,
where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span },
span,
}
}
/// Lifetimes and bounds on type parameters

View File

@ -6,7 +6,6 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::{is_range_literal, ExprKind, Node};
use rustc_index::vec::Idx;
use rustc_middle::mir::interpret::{sign_extend, truncate};
@ -511,10 +510,6 @@ enum FfiResult<'tcx> {
FfiUnsafe { ty: Ty<'tcx>, reason: &'static str, help: Option<&'static str> },
}
fn is_zst<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, ty: Ty<'tcx>) -> bool {
tcx.layout_of(tcx.param_env(did).and(ty)).map(|layout| layout.is_zst()).unwrap_or(false)
}
fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
match ty.kind {
ty::FnPtr(_) => true,
@ -523,7 +518,7 @@ fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
for field in field_def.all_fields() {
let field_ty =
tcx.normalize_erasing_regions(ParamEnv::reveal_all(), field.ty(tcx, substs));
if is_zst(tcx, field.did, field_ty) {
if field_ty.is_zst(tcx, field.did) {
continue;
}
@ -653,32 +648,43 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
};
}
// We can't completely trust repr(C) and repr(transparent) markings;
// make sure the fields are actually safe.
let mut all_phantom = true;
for field in &def.non_enum_variant().fields {
let field_ty = cx.normalize_erasing_regions(
ParamEnv::reveal_all(),
field.ty(cx, substs),
);
// repr(transparent) types are allowed to have arbitrary ZSTs, not just
// PhantomData -- skip checking all ZST fields
if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
continue;
if def.repr.transparent() {
// Can assume that only one field is not a ZST, so only check
// that field's type for FFI-safety.
if let Some(field) =
def.transparent_newtype_field(cx, self.cx.param_env)
{
let field_ty = cx.normalize_erasing_regions(
self.cx.param_env,
field.ty(cx, substs),
);
self.check_type_for_ffi(cache, field_ty)
} else {
FfiSafe
}
let r = self.check_type_for_ffi(cache, field_ty);
match r {
FfiSafe => {
all_phantom = false;
}
FfiPhantom(..) => {}
FfiUnsafe { .. } => {
return r;
} else {
// We can't completely trust repr(C) markings; make sure the fields are
// actually safe.
let mut all_phantom = true;
for field in &def.non_enum_variant().fields {
let field_ty = cx.normalize_erasing_regions(
self.cx.param_env,
field.ty(cx, substs),
);
let r = self.check_type_for_ffi(cache, field_ty);
match r {
FfiSafe => {
all_phantom = false;
}
FfiPhantom(..) => {}
FfiUnsafe { .. } => {
return r;
}
}
}
}
if all_phantom { FfiPhantom(ty) } else { FfiSafe }
if all_phantom { FfiPhantom(ty) } else { FfiSafe }
}
}
AdtKind::Union => {
if !def.repr.c() && !def.repr.transparent() {
@ -708,7 +714,7 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
);
// repr(transparent) types are allowed to have arbitrary ZSTs, not just
// PhantomData -- skip checking all ZST fields.
if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
if def.repr.transparent() && field_ty.is_zst(cx, field.did) {
continue;
}
let r = self.check_type_for_ffi(cache, field_ty);
@ -774,7 +780,7 @@ fn check_type_for_ffi(&self, cache: &mut FxHashSet<Ty<'tcx>>, ty: Ty<'tcx>) -> F
);
// repr(transparent) types are allowed to have arbitrary ZSTs, not
// just PhantomData -- skip checking all ZST fields.
if def.repr.transparent() && is_zst(cx, field.did, field_ty) {
if def.repr.transparent() && field_ty.is_zst(cx, field.did) {
continue;
}
let r = self.check_type_for_ffi(cache, field_ty);
@ -946,7 +952,13 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
}
}
fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>, is_static: bool) {
fn check_type_for_ffi_and_report_errors(
&mut self,
sp: Span,
ty: Ty<'tcx>,
is_static: bool,
is_return_type: bool,
) {
// We have to check for opaque types before `normalize_erasing_regions`,
// which will replace opaque types with their underlying concrete type.
if self.check_for_opaque_ty(sp, ty) {
@ -957,19 +969,29 @@ fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>, is_st
// it is only OK to use this function because extern fns cannot have
// any generic types right now:
let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
// C doesn't really support passing arrays by value.
// The only way to pass an array by value is through a struct.
// So we first test that the top level isn't an array,
// and then recursively check the types inside.
// C doesn't really support passing arrays by value - the only way to pass an array by value
// is through a struct. So, first test that the top level isn't an array, and then
// recursively check the types inside.
if !is_static && self.check_for_array_ty(sp, ty) {
return;
}
// Don't report FFI errors for unit return types. This check exists here, and not in
// `check_foreign_fn` (where it would make more sense) so that normalization has definitely
// happened.
if is_return_type && ty.is_unit() {
return;
}
match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
FfiResult::FfiSafe => {}
FfiResult::FfiPhantom(ty) => {
self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
}
// If `ty` is a `repr(transparent)` newtype, and the non-zero-sized type is a generic
// argument, which after substitution, is `()`, then this branch can be hit.
FfiResult::FfiUnsafe { ty, .. } if is_return_type && ty.is_unit() => return,
FfiResult::FfiUnsafe { ty, reason, help } => {
self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
}
@ -982,21 +1004,19 @@ fn check_foreign_fn(&mut self, id: hir::HirId, decl: &hir::FnDecl<'_>) {
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
for (input_ty, input_hir) in sig.inputs().iter().zip(decl.inputs) {
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false);
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false, false);
}
if let hir::FnRetTy::Return(ref ret_hir) = decl.output {
let ret_ty = sig.output();
if !ret_ty.is_unit() {
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false);
}
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false, true);
}
}
fn check_foreign_static(&mut self, id: hir::HirId, span: Span) {
let def_id = self.cx.tcx.hir().local_def_id(id);
let ty = self.cx.tcx.type_of(def_id);
self.check_type_for_ffi_and_report_errors(span, ty, true);
self.check_type_for_ffi_and_report_errors(span, ty, true, false);
}
}

View File

@ -2390,6 +2390,29 @@ pub fn destructor(&self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
tcx.adt_sized_constraint(self.did).0
}
/// `repr(transparent)` structs can have a single non-ZST field, this function returns that
/// field.
pub fn transparent_newtype_field(
&self,
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
) -> Option<&FieldDef> {
assert!(self.is_struct() && self.repr.transparent());
for field in &self.non_enum_variant().fields {
let field_ty = tcx.normalize_erasing_regions(
param_env,
field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.did)),
);
if !field_ty.is_zst(tcx, self.did) {
return Some(field);
}
}
None
}
}
impl<'tcx> FieldDef {

View File

@ -2186,6 +2186,11 @@ pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
}
}
}
/// Is this a zero-sized type?
pub fn is_zst(&'tcx self, tcx: TyCtxt<'tcx>, did: DefId) -> bool {
tcx.layout_of(tcx.param_env(did).and(self)).map(|layout| layout.is_zst()).unwrap_or(false)
}
}
/// Typed constant value.

View File

@ -157,6 +157,7 @@ pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
Ok(ast::Generics {
params,
where_clause: WhereClause {
has_where_token: false,
predicates: Vec::new(),
span: self.prev_token.span.shrink_to_hi(),
},
@ -170,12 +171,16 @@ pub(super) fn parse_generics(&mut self) -> PResult<'a, ast::Generics> {
/// where T : Trait<U, V> + 'b, 'a : 'b
/// ```
pub(super) fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
let mut where_clause =
WhereClause { predicates: Vec::new(), span: self.prev_token.span.shrink_to_hi() };
let mut where_clause = WhereClause {
has_where_token: false,
predicates: Vec::new(),
span: self.prev_token.span.shrink_to_hi(),
};
if !self.eat_keyword(kw::Where) {
return Ok(where_clause);
}
where_clause.has_where_token = true;
let lo = self.prev_token.span;
// We are considering adding generics to the `where` keyword as an alternative higher-rank

View File

@ -629,6 +629,7 @@ fn lookup_import_candidates_from_module<FilterFn>(
&mut self,
lookup_ident: Ident,
namespace: Namespace,
parent_scope: &ParentScope<'a>,
start_module: Module<'a>,
crate_name: Ident,
filter_fn: FilterFn,
@ -655,7 +656,11 @@ fn lookup_import_candidates_from_module<FilterFn>(
}
// collect results based on the filter function
if ident.name == lookup_ident.name && ns == namespace {
// avoid suggesting anything from the same module in which we are resolving
if ident.name == lookup_ident.name
&& ns == namespace
&& !ptr::eq(in_module, parent_scope.module)
{
let res = name_binding.res();
if filter_fn(res) {
// create the path
@ -680,7 +685,9 @@ fn lookup_import_candidates_from_module<FilterFn>(
Res::Def(DefKind::Ctor(..), did) => this.parent(did),
_ => res.opt_def_id(),
};
candidates.push(ImportSuggestion { did, descr: res.descr(), path });
if candidates.iter().all(|v: &ImportSuggestion| v.did != did) {
candidates.push(ImportSuggestion { did, descr: res.descr(), path });
}
}
}
}
@ -722,6 +729,7 @@ fn lookup_import_candidates_from_module<FilterFn>(
&mut self,
lookup_ident: Ident,
namespace: Namespace,
parent_scope: &ParentScope<'a>,
filter_fn: FilterFn,
) -> Vec<ImportSuggestion>
where
@ -730,6 +738,7 @@ fn lookup_import_candidates_from_module<FilterFn>(
let mut suggestions = self.lookup_import_candidates_from_module(
lookup_ident,
namespace,
parent_scope,
self.graph_root,
Ident::with_dummy_span(kw::Crate),
&filter_fn,
@ -754,6 +763,7 @@ fn lookup_import_candidates_from_module<FilterFn>(
suggestions.extend(self.lookup_import_candidates_from_module(
lookup_ident,
namespace,
parent_scope,
crate_root,
ident,
&filter_fn,

View File

@ -212,7 +212,7 @@ pub(crate) fn smart_resolve_report_errors(
let ident = path.last().unwrap().ident;
let candidates = self
.r
.lookup_import_candidates(ident, ns, is_expected)
.lookup_import_candidates(ident, ns, &self.parent_scope, is_expected)
.drain(..)
.filter(|ImportSuggestion { did, .. }| {
match (did, res.and_then(|res| res.opt_def_id())) {
@ -223,7 +223,8 @@ pub(crate) fn smart_resolve_report_errors(
.collect::<Vec<_>>();
let crate_def_id = DefId::local(CRATE_DEF_INDEX);
if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) {
let enum_candidates = self.r.lookup_import_candidates(ident, ns, is_enum_variant);
let enum_candidates =
self.r.lookup_import_candidates(ident, ns, &self.parent_scope, is_enum_variant);
let mut enum_candidates = enum_candidates
.iter()
.map(|suggestion| import_candidate_to_enum_paths(&suggestion))

View File

@ -2235,7 +2235,8 @@ enum FindBindingResult<'a> {
Res::Def(DefKind::Mod, _) => true,
_ => false,
};
let mut candidates = self.lookup_import_candidates(ident, TypeNS, is_mod);
let mut candidates =
self.lookup_import_candidates(ident, TypeNS, parent_scope, is_mod);
candidates.sort_by_cached_key(|c| {
(c.path.segments.len(), pprust::path_to_string(&c.path))
});

View File

@ -20,9 +20,9 @@ pub fn opts() -> TargetOptions {
late_link_args.insert(
LinkerFlavor::Gcc,
vec![
"-lmsvcrt".to_string(),
"-lmingwex".to_string(),
"-lmingw32".to_string(),
"-lmsvcrt".to_string(),
// mingw's msvcrt is a weird hybrid import library and static library.
// And it seems that the linker fails to use import symbols from msvcrt
// that are required from functions in msvcrt in certain cases. For example

View File

@ -331,6 +331,16 @@ fn assemble_candidates_from_impls(
) -> Result<(), SelectionError<'tcx>> {
debug!("assemble_candidates_from_impls(obligation={:?})", obligation);
// Essentially any user-written impl will match with an error type,
// so creating `ImplCandidates` isn't useful. However, we might
// end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized)
// This helps us avoid overflow: see issue #72839
// Since compilation is already guaranteed to fail, this is just
// to try to show the 'nicest' possible errors to the user.
if obligation.references_error() {
return Ok(());
}
self.tcx().for_each_relevant_impl(
obligation.predicate.def_id(),
obligation.predicate.skip_binder().trait_ref.self_ty(),

View File

@ -1104,6 +1104,14 @@ fn candidate_from_obligation_no_cache<'o>(
// who might care about this case, like coherence, should use
// that function).
if candidates.is_empty() {
// If there's an error type, 'downgrade' our result from
// `Err(Unimplemented)` to `Ok(None)`. This helps us avoid
// emitting additional spurious errors, since we're guaranteed
// to have emitted at least one.
if stack.obligation.references_error() {
debug!("no results for error type, treating as ambiguous");
return Ok(None);
}
return Err(Unimplemented);
}

View File

@ -251,7 +251,10 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
// fields of ADT.
let tcx = self.tcx();
for field_ty in adt_def.all_fields().map(|field| field.ty(tcx, substs)) {
if field_ty.visit_with(self) {
let ty = self.tcx().normalize_erasing_regions(ty::ParamEnv::empty(), field_ty);
debug!("structural-match ADT: field_ty={:?}, ty={:?}", field_ty, ty);
if ty.visit_with(self) {
// found an ADT without structural-match; halt visiting!
assert!(self.found.is_some());
return true;

View File

@ -0,0 +1,20 @@
// Regression test for #72819: ICE due to failure in resolving the const generic in `Arr`'s type
// bounds.
#![feature(const_generics)]
#![allow(incomplete_features)]
struct Arr<const N: usize>
where Assert::<{N < usize::max_value() / 2}>: IsTrue,
//~^ ERROR constant expression depends on a generic parameter
{
}
enum Assert<const CHECK: bool> {}
trait IsTrue {}
impl IsTrue for Assert<true> {}
fn main() {
let x: Arr<{usize::max_value()}> = Arr {};
}

View File

@ -0,0 +1,10 @@
error: constant expression depends on a generic parameter
--> $DIR/issue-72819-generic-in-const-eval.rs:7:47
|
LL | where Assert::<{N < usize::max_value() / 2}>: IsTrue,
| ^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to previous error

View File

@ -4,12 +4,10 @@ error[E0433]: failed to resolve: use of undeclared type or module `HashMap`
LL | let mut map = HashMap::new();
| ^^^^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this struct
|
LL | use std::collections::HashMap;
|
LL | use std::collections::hash_map::HashMap;
|
error: aborting due to previous error

View File

@ -16,9 +16,7 @@ LL | Vec::new();
| ^^^ not found in this scope
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing one of these items
|
LL | use std::prelude::v1::Vec;
help: consider importing this struct
|
LL | use std::vec::Vec;
|

View File

@ -11,8 +11,6 @@ fn main() {
// return type, which can't depend on the obligation.
fn cycle1() -> impl Clone {
//~^ ERROR cycle detected
//~| ERROR cycle detected
//~| ERROR cycle detected
send(cycle2().clone());
//~^ ERROR cannot be sent between threads safely

View File

@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
note: ...which requires computing type of `cycle2::{{opaque}}#0`...
--> $DIR/auto-trait-leak.rs:22:16
--> $DIR/auto-trait-leak.rs:20:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires borrow-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
--> $DIR/auto-trait-leak.rs:20:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@ -84,178 +84,8 @@ LL | | Rc::new(String::from("foo"))
LL | | }
| |_^
error[E0391]: cycle detected when computing type of `cycle1::{{opaque}}#0`
--> $DIR/auto-trait-leak.rs:12:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
|
note: ...which requires borrow-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
note: ...which requires computing type of `cycle2::{{opaque}}#0`...
--> $DIR/auto-trait-leak.rs:22:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires borrow-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires computing type of `cycle1::{{opaque}}#0`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/auto-trait-leak.rs:1:1
|
LL | / use std::cell::Cell;
LL | | use std::rc::Rc;
LL | |
LL | | fn send<T: Send>(_: T) {}
... |
LL | | Rc::new(String::from("foo"))
LL | | }
| |_^
error[E0391]: cycle detected when computing type of `cycle1::{{opaque}}#0`
--> $DIR/auto-trait-leak.rs:12:16
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^
|
note: ...which requires borrow-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle1`...
--> $DIR/auto-trait-leak.rs:12:1
|
LL | fn cycle1() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`...
note: ...which requires computing type of `cycle2::{{opaque}}#0`...
--> $DIR/auto-trait-leak.rs:22:16
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^
note: ...which requires borrow-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires unsafety-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires building MIR for `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `cycle2`...
--> $DIR/auto-trait-leak.rs:22:1
|
LL | fn cycle2() -> impl Clone {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which again requires computing type of `cycle1::{{opaque}}#0`, completing the cycle
note: cycle used when checking item types in top-level module
--> $DIR/auto-trait-leak.rs:1:1
|
LL | / use std::cell::Cell;
LL | | use std::rc::Rc;
LL | |
LL | | fn send<T: Send>(_: T) {}
... |
LL | | Rc::new(String::from("foo"))
LL | | }
| |_^
error[E0277]: `std::rc::Rc<std::string::String>` cannot be sent between threads safely
--> $DIR/auto-trait-leak.rs:16:5
--> $DIR/auto-trait-leak.rs:14:5
|
LL | fn send<T: Send>(_: T) {}
| ---- required by this bound in `send`
@ -269,7 +99,7 @@ LL | fn cycle2() -> impl Clone {
= help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
= note: required because it appears within the type `impl std::clone::Clone`
error: aborting due to 4 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0391.
For more information about an error, try `rustc --explain E0277`.

View File

@ -30,11 +30,10 @@ LL | use std::fmt::Result;
|
LL | use std::io::Result;
|
LL | use std::prelude::v1::Result;
|
LL | use std::result::Result;
|
and 1 other candidate
LL | use std::thread::Result;
|
error[E0573]: expected type, found variant `Result`
--> $DIR/issue-17546.rs:30:13
@ -48,11 +47,10 @@ LL | use std::fmt::Result;
|
LL | use std::io::Result;
|
LL | use std::prelude::v1::Result;
|
LL | use std::result::Result;
|
and 1 other candidate
LL | use std::thread::Result;
|
error[E0573]: expected type, found variant `NoResult`
--> $DIR/issue-17546.rs:35:15

View File

@ -0,0 +1,19 @@
// Regression test for issue #72839
// Tests that we do not overflow during trait selection after
// a type error occurs
use std::ops::Rem;
trait Foo {}
struct MyStruct<T>(T);
impl<T, U> Rem<MyStruct<T>> for MyStruct<U> where MyStruct<U>: Rem<MyStruct<T>> {
type Output = u8;
fn rem(self, _: MyStruct<T>) -> Self::Output {
panic!()
}
}
fn main() {}
fn foo() {
if missing_var % 8 == 0 {} //~ ERROR cannot find
}

View File

@ -0,0 +1,9 @@
error[E0425]: cannot find value `missing_var` in this scope
--> $DIR/issue-72839-error-overflow.rs:18:8
|
LL | if missing_var % 8 == 0 {}
| ^^^^^^^^^^^ not found in this scope
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.

View File

@ -3,11 +3,6 @@ error[E0574]: expected struct, variant or union type, found type parameter `T`
|
LL | let t = T { i: 0 };
| ^ not a struct, variant or union type
|
help: consider importing this struct instead
|
LL | use T;
|
error[E0599]: no function or associated item named `f` found for type parameter `Foo` in the current scope
--> $DIR/lexical-scopes.rs:10:10

View File

@ -0,0 +1,17 @@
// check-pass
#![deny(improper_ctypes)]
// This test checks that return types are normalized before being checked for FFI-safety, and that
// transparent newtype wrappers are FFI-safe if the type being wrapped is FFI-safe.
#[repr(transparent)]
pub struct W<T>(T);
extern "C" {
pub fn bare() -> ();
pub fn normalize() -> <() as ToOwned>::Owned;
pub fn transparent() -> W<()>;
}
fn main() {}

View File

@ -0,0 +1,23 @@
// run-pass
trait EnumSetType {
type Repr;
}
enum Enum8 { }
impl EnumSetType for Enum8 {
type Repr = u8;
}
#[derive(PartialEq, Eq)]
struct EnumSet<T: EnumSetType> {
__enumset_underlying: T::Repr,
}
const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
fn main() {
match CONST_SET {
CONST_SET => { /* ok */ }
_ => panic!("match fell through?"),
}
}

View File

@ -15,12 +15,10 @@ error[E0404]: expected trait, found derive macro `Clone`
LL | impl Clone for Test {}
| ^^^^^ not a trait
|
help: consider importing one of these items instead
help: consider importing this trait instead
|
LL | use std::clone::Clone;
|
LL | use std::prelude::v1::Clone;
|
error[E0405]: cannot find trait `Iterator` in this scope
--> $DIR/no-implicit-prelude-nested.rs:13:14
@ -28,12 +26,10 @@ error[E0405]: cannot find trait `Iterator` in this scope
LL | impl Iterator for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this trait
|
LL | use std::iter::Iterator;
|
LL | use std::prelude::v1::Iterator;
|
error[E0405]: cannot find trait `ToString` in this scope
--> $DIR/no-implicit-prelude-nested.rs:14:14
@ -41,9 +37,7 @@ error[E0405]: cannot find trait `ToString` in this scope
LL | impl ToString for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing one of these items
|
LL | use std::prelude::v1::ToString;
help: consider importing this trait
|
LL | use std::string::ToString;
|
@ -60,12 +54,10 @@ error[E0425]: cannot find function `drop` in this scope
LL | drop(2)
| ^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this function
|
LL | use std::mem::drop;
|
LL | use std::prelude::v1::drop;
|
error[E0405]: cannot find trait `Add` in this scope
--> $DIR/no-implicit-prelude-nested.rs:23:10
@ -84,12 +76,10 @@ error[E0404]: expected trait, found derive macro `Clone`
LL | impl Clone for Test {}
| ^^^^^ not a trait
|
help: consider importing one of these items instead
help: consider importing this trait instead
|
LL | use std::clone::Clone;
|
LL | use std::prelude::v1::Clone;
|
error[E0405]: cannot find trait `Iterator` in this scope
--> $DIR/no-implicit-prelude-nested.rs:25:10
@ -97,12 +87,10 @@ error[E0405]: cannot find trait `Iterator` in this scope
LL | impl Iterator for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this trait
|
LL | use std::iter::Iterator;
|
LL | use std::prelude::v1::Iterator;
|
error[E0405]: cannot find trait `ToString` in this scope
--> $DIR/no-implicit-prelude-nested.rs:26:10
@ -110,9 +98,7 @@ error[E0405]: cannot find trait `ToString` in this scope
LL | impl ToString for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing one of these items
|
LL | use std::prelude::v1::ToString;
help: consider importing this trait
|
LL | use std::string::ToString;
|
@ -129,12 +115,10 @@ error[E0425]: cannot find function `drop` in this scope
LL | drop(2)
| ^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this function
|
LL | use std::mem::drop;
|
LL | use std::prelude::v1::drop;
|
error[E0405]: cannot find trait `Add` in this scope
--> $DIR/no-implicit-prelude-nested.rs:38:14
@ -153,12 +137,10 @@ error[E0404]: expected trait, found derive macro `Clone`
LL | impl Clone for Test {}
| ^^^^^ not a trait
|
help: consider importing one of these items instead
help: consider importing this trait instead
|
LL | use std::clone::Clone;
|
LL | use std::prelude::v1::Clone;
|
error[E0405]: cannot find trait `Iterator` in this scope
--> $DIR/no-implicit-prelude-nested.rs:40:14
@ -166,12 +148,10 @@ error[E0405]: cannot find trait `Iterator` in this scope
LL | impl Iterator for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this trait
|
LL | use std::iter::Iterator;
|
LL | use std::prelude::v1::Iterator;
|
error[E0405]: cannot find trait `ToString` in this scope
--> $DIR/no-implicit-prelude-nested.rs:41:14
@ -179,9 +159,7 @@ error[E0405]: cannot find trait `ToString` in this scope
LL | impl ToString for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing one of these items
|
LL | use std::prelude::v1::ToString;
help: consider importing this trait
|
LL | use std::string::ToString;
|
@ -198,12 +176,10 @@ error[E0425]: cannot find function `drop` in this scope
LL | drop(2)
| ^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this function
|
LL | use std::mem::drop;
|
LL | use std::prelude::v1::drop;
|
error: aborting due to 18 previous errors

View File

@ -15,12 +15,10 @@ error[E0404]: expected trait, found derive macro `Clone`
LL | impl Clone for Test {}
| ^^^^^ not a trait
|
help: consider importing one of these items instead
help: consider importing this trait instead
|
LL | use std::clone::Clone;
|
LL | use std::prelude::v1::Clone;
|
error[E0405]: cannot find trait `Iterator` in this scope
--> $DIR/no-implicit-prelude.rs:12:6
@ -28,12 +26,10 @@ error[E0405]: cannot find trait `Iterator` in this scope
LL | impl Iterator for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this trait
|
LL | use std::iter::Iterator;
|
LL | use std::prelude::v1::Iterator;
|
error[E0405]: cannot find trait `ToString` in this scope
--> $DIR/no-implicit-prelude.rs:13:6
@ -41,9 +37,7 @@ error[E0405]: cannot find trait `ToString` in this scope
LL | impl ToString for Test {}
| ^^^^^^^^ not found in this scope
|
help: consider importing one of these items
|
LL | use std::prelude::v1::ToString;
help: consider importing this trait
|
LL | use std::string::ToString;
|
@ -60,12 +54,10 @@ error[E0425]: cannot find function `drop` in this scope
LL | drop(2)
| ^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this function
|
LL | use std::mem::drop;
|
LL | use std::prelude::v1::drop;
|
error: aborting due to 6 previous errors

View File

@ -0,0 +1,18 @@
// aux-build:test-macros.rs
extern crate test_macros;
use test_macros::recollect_attr;
#[recollect_attr]
struct FieldStruct where {
field: MissingType1 //~ ERROR cannot find
}
#[recollect_attr]
struct TupleStruct(MissingType2) where; //~ ERROR cannot find
enum MyEnum where {
Variant(MissingType3) //~ ERROR cannot find
}
fn main() {}

View File

@ -0,0 +1,21 @@
error[E0412]: cannot find type `MissingType1` in this scope
--> $DIR/empty-where-clause.rs:8:12
|
LL | field: MissingType1
| ^^^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `MissingType2` in this scope
--> $DIR/empty-where-clause.rs:12:20
|
LL | struct TupleStruct(MissingType2) where;
| ^^^^^^^^^^^^ not found in this scope
error[E0412]: cannot find type `MissingType3` in this scope
--> $DIR/empty-where-clause.rs:15:13
|
LL | Variant(MissingType3)
| ^^^^^^^^^^^^ not found in this scope
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0412`.

View File

@ -27,10 +27,6 @@ LL | pass_dollar_crate!();
| ^^^^^^^^^^^^^^^^^^^^^ not found in `$crate`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing this struct
|
LL | use ItemUse;
|
error: aborting due to 4 previous errors

View File

@ -10,12 +10,10 @@ error[E0433]: failed to resolve: use of undeclared type or module `HashMap`
LL | let x1 = HashMap::new();
| ^^^^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this struct
|
LL | use std::collections::HashMap;
|
LL | use std::collections::hash_map::HashMap;
|
error[E0412]: cannot find type `HashMap` in this scope
--> $DIR/use_suggestion.rs:5:13
@ -23,12 +21,10 @@ error[E0412]: cannot find type `HashMap` in this scope
LL | let y1: HashMap;
| ^^^^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this struct
|
LL | use std::collections::HashMap;
|
LL | use std::collections::hash_map::HashMap;
|
error[E0412]: cannot find type `GooMap` in this scope
--> $DIR/use_suggestion.rs:6:13

View File

@ -26,12 +26,10 @@ error[E0412]: cannot find type `HashMap` in this scope
LL | type Dict<K, V> = HashMap<K, V>;
| ^^^^^^^ not found in this scope
|
help: consider importing one of these items
help: consider importing this struct
|
LL | use std::collections::HashMap;
|
LL | use std::collections::hash_map::HashMap;
|
error: aborting due to 3 previous errors

View File

@ -20,7 +20,7 @@ Hey LLVM ICE-breakers! This bug has been identified as a good
[instructions] for tackling these sorts of bugs. Maybe take a look?
Thanks! <3
[instructions]: https://rustc-dev-guide.rust-lang.org/ice-breaker/llvm.html
[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/llvm.html
"""
label = "ICEBreaker-LLVM"
@ -32,10 +32,30 @@ Hey Cleanup Crew ICE-breakers! This bug has been identified as a good
[instructions] for tackling these sorts of bugs. Maybe take a look?
Thanks! <3
[instructions]: https://rustc-dev-guide.rust-lang.org/ice-breaker/cleanup-crew.html
[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/cleanup-crew.html
"""
label = "ICEBreaker-Cleanup-Crew"
[ping.windows]
message = """\
Hey Windows Group! This bug has been identified as a good "Windows candidate".
In case it's useful, here are some [instructions] for tackling these sorts of
bugs. Maybe take a look?
Thanks! <3
[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/windows.html
"""
label = "O-windows"
[ping.arm]
message = """\
Hey ARM Group! This bug has been identified as a good "ARM candidate".
In case it's useful, here are some [instructions] for tackling these sorts of
bugs. Maybe take a look?
Thanks! <3
[instructions]: https://rustc-dev-guide.rust-lang.org/notification-groups/arm.html
"""
label = "O-ARM"
[prioritize]
label = "I-prioritize"
prioritize_on = ["regression-from-stable-to-stable", "regression-from-stable-to-beta", "regression-from-stable-to-nightly"]