diff --git a/.travis.yml b/.travis.yml index 091a5abdaa216..1119304189cce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -176,8 +176,6 @@ matrix: if: branch = auto - env: IMAGE=x86_64-gnu-distcheck if: branch = auto - - env: IMAGE=x86_64-gnu-incremental - if: branch = auto - stage: publish toolstate if: branch = master AND type = push diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 44073a5b07572..db79c68bfce5c 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -512,7 +512,7 @@ impl Step for Test { fn should_run(run: ShouldRun) -> ShouldRun { let builder = run.builder; - run.krate("test").default_condition(builder.config.compiler_docs) + run.krate("test").default_condition(builder.build.config.docs) } fn make_run(run: RunConfig) { @@ -555,6 +555,9 @@ impl Step for Test { let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "doc"); compile::test_cargo(build, &compiler, target, &mut cargo); + + cargo.arg("--no-deps").arg("-p").arg("test"); + build.run(&mut cargo); cp_r(&my_out, &out); } diff --git a/src/ci/docker/x86_64-gnu-incremental/Dockerfile b/src/ci/docker/x86_64-gnu-incremental/Dockerfile deleted file mode 100644 index 7304ed6015cc9..0000000000000 --- a/src/ci/docker/x86_64-gnu-incremental/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM ubuntu:16.04 - -RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ - ca-certificates \ - python2.7 \ - git \ - cmake \ - sudo \ - gdb \ - xz-utils - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu -ENV RUSTFLAGS -Zincremental=/tmp/rust-incr-cache -ENV RUST_CHECK_TARGET check -ENV CARGO_INCREMENTAL 0 diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 536d682566a72..5cc517a4afd1b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -780,8 +780,9 @@ impl<'a> LoweringContext<'a> { _ => None, }), |this| { + let itctx = ImplTraitContext::Universal(parent_id); this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| { - (this.lower_generics(generics), f(this)) + (this.lower_generics(generics, itctx), f(this)) }) }, ); @@ -1043,7 +1044,11 @@ impl<'a> LoweringContext<'a> { }), |this| { hir::TyBareFn(P(hir::BareFnTy { - generic_params: this.lower_generic_params(&f.generic_params, &NodeMap()), + generic_params: this.lower_generic_params( + &f.generic_params, + &NodeMap(), + ImplTraitContext::Disallowed, + ), unsafety: this.lower_unsafety(f.unsafety), abi: f.abi, decl: this.lower_fn_decl(&f.decl, None, false), @@ -1784,7 +1789,12 @@ impl<'a> LoweringContext<'a> { } } - fn lower_ty_param(&mut self, tp: &TyParam, add_bounds: &[TyParamBound]) -> hir::TyParam { + fn lower_ty_param( + &mut self, + tp: &TyParam, + add_bounds: &[TyParamBound], + itctx: ImplTraitContext, + ) -> hir::TyParam { let mut name = self.lower_ident(tp.ident); // Don't expose `Self` (recovered "keyword used as ident" parse error). @@ -1794,7 +1804,6 @@ impl<'a> LoweringContext<'a> { name = Symbol::gensym("Self"); } - let itctx = ImplTraitContext::Universal(self.resolver.definitions().local_def_id(tp.id)); let mut bounds = self.lower_bounds(&tp.bounds, itctx); if !add_bounds.is_empty() { bounds = bounds @@ -1878,6 +1887,7 @@ impl<'a> LoweringContext<'a> { &mut self, params: &Vec, add_bounds: &NodeMap>, + itctx: ImplTraitContext, ) -> hir::HirVec { params .iter() @@ -1888,12 +1898,13 @@ impl<'a> LoweringContext<'a> { GenericParam::Type(ref ty_param) => hir::GenericParam::Type(self.lower_ty_param( ty_param, add_bounds.get(&ty_param.id).map_or(&[][..], |x| &x), + itctx, )), }) .collect() } - fn lower_generics(&mut self, g: &Generics) -> hir::Generics { + fn lower_generics(&mut self, g: &Generics, itctx: ImplTraitContext) -> hir::Generics { // Collect `?Trait` bounds in where clause and move them to parameter definitions. // FIXME: This could probably be done with less rightward drift. Also looks like two control // paths where report_error is called are also the only paths that advance to after @@ -1946,7 +1957,7 @@ impl<'a> LoweringContext<'a> { } hir::Generics { - params: self.lower_generic_params(&g.params, &add_bounds), + params: self.lower_generic_params(&g.params, &add_bounds, itctx), where_clause: self.lower_where_clause(&g.where_clause), span: g.span, } @@ -1980,6 +1991,7 @@ impl<'a> LoweringContext<'a> { bound_generic_params: this.lower_generic_params( bound_generic_params, &NodeMap(), + ImplTraitContext::Disallowed, ), bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed), bounds: bounds @@ -2063,7 +2075,8 @@ impl<'a> LoweringContext<'a> { p: &PolyTraitRef, itctx: ImplTraitContext, ) -> hir::PolyTraitRef { - let bound_generic_params = self.lower_generic_params(&p.bound_generic_params, &NodeMap()); + let bound_generic_params = + self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx); let trait_ref = self.with_parent_impl_lifetime_defs( &bound_generic_params .iter() @@ -2218,7 +2231,7 @@ impl<'a> LoweringContext<'a> { ItemKind::GlobalAsm(ref ga) => hir::ItemGlobalAsm(self.lower_global_asm(ga)), ItemKind::Ty(ref t, ref generics) => hir::ItemTy( self.lower_ty(t, ImplTraitContext::Disallowed), - self.lower_generics(generics), + self.lower_generics(generics, ImplTraitContext::Disallowed), ), ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemEnum( hir::EnumDef { @@ -2228,15 +2241,21 @@ impl<'a> LoweringContext<'a> { .map(|x| self.lower_variant(x)) .collect(), }, - self.lower_generics(generics), + self.lower_generics(generics, ImplTraitContext::Disallowed), ), ItemKind::Struct(ref struct_def, ref generics) => { let struct_def = self.lower_variant_data(struct_def); - hir::ItemStruct(struct_def, self.lower_generics(generics)) + hir::ItemStruct( + struct_def, + self.lower_generics(generics, ImplTraitContext::Disallowed), + ) } ItemKind::Union(ref vdata, ref generics) => { let vdata = self.lower_variant_data(vdata); - hir::ItemUnion(vdata, self.lower_generics(generics)) + hir::ItemUnion( + vdata, + self.lower_generics(generics, ImplTraitContext::Disallowed), + ) } ItemKind::Impl( unsafety, @@ -2315,13 +2334,13 @@ impl<'a> LoweringContext<'a> { hir::ItemTrait( self.lower_is_auto(is_auto), self.lower_unsafety(unsafety), - self.lower_generics(generics), + self.lower_generics(generics, ImplTraitContext::Disallowed), bounds, items, ) } ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemTraitAlias( - self.lower_generics(generics), + self.lower_generics(generics, ImplTraitContext::Disallowed), self.lower_bounds(bounds, ImplTraitContext::Disallowed), ), ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"), @@ -2456,7 +2475,7 @@ impl<'a> LoweringContext<'a> { let (generics, node) = match i.node { TraitItemKind::Const(ref ty, ref default) => ( - this.lower_generics(&i.generics), + this.lower_generics(&i.generics, ImplTraitContext::Disallowed), hir::TraitItemKind::Const( this.lower_ty(ty, ImplTraitContext::Disallowed), default @@ -2497,7 +2516,7 @@ impl<'a> LoweringContext<'a> { ) } TraitItemKind::Type(ref bounds, ref default) => ( - this.lower_generics(&i.generics), + this.lower_generics(&i.generics, ImplTraitContext::Disallowed), hir::TraitItemKind::Type( this.lower_bounds(bounds, ImplTraitContext::Disallowed), default @@ -2554,7 +2573,7 @@ impl<'a> LoweringContext<'a> { ImplItemKind::Const(ref ty, ref expr) => { let body_id = this.lower_body(None, |this| this.lower_expr(expr)); ( - this.lower_generics(&i.generics), + this.lower_generics(&i.generics, ImplTraitContext::Disallowed), hir::ImplItemKind::Const( this.lower_ty(ty, ImplTraitContext::Disallowed), body_id, @@ -2585,7 +2604,7 @@ impl<'a> LoweringContext<'a> { ) } ImplItemKind::Type(ref ty) => ( - this.lower_generics(&i.generics), + this.lower_generics(&i.generics, ImplTraitContext::Disallowed), hir::ImplItemKind::Type(this.lower_ty(ty, ImplTraitContext::Disallowed)), ), ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index eb5df697216a3..725ea9734abf4 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -533,10 +533,14 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> match r { // ignore bound regions that appear in the type (e.g., this // would ignore `'r` in a type like `for<'r> fn(&'r u32)`. - ty::ReLateBound(..) => return r, + ty::ReLateBound(..) | // ignore `'static`, as that can appear anywhere - ty::ReStatic => return r, + ty::ReStatic | + + // ignore `ReScope`, as that can appear anywhere + // See `src/test/run-pass/issue-49556.rs` for example. + ty::ReScope(..) => return r, _ => { } } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 96c2309882108..8d314e251972d 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -181,7 +181,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.msg_span_from_early_bound_and_free_regions(region) }, ty::ReStatic => ("the static lifetime".to_owned(), None), - _ => bug!(), + _ => bug!("{:?}", region), } } diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 91df6cabf3a8b..5e96f4eb576f5 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use syntax::ast; +use syntax::symbol::InternedString; use syntax_pos::Span; use ty::{self, Ty}; @@ -53,7 +53,7 @@ pub enum TypeVariableOrigin { MiscVariable(Span), NormalizeProjectionType(Span), TypeInference(Span), - TypeParameterDefinition(Span, ast::Name), + TypeParameterDefinition(Span, InternedString), /// one of the upvars or closure kind parameters in a `ClosureSubsts` /// (before it has been determined) diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 6bf0c5d1ba3e3..5875e5e4097af 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -503,8 +503,37 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { self.resolve_type_vars_or_error(expr.hir_id, self.tables.expr_ty_adjusted_opt(expr)) } + /// Returns the type of value that this pattern matches against. + /// Some non-obvious cases: + /// + /// - a `ref x` binding matches against a value of type `T` and gives + /// `x` the type `&T`; we return `T`. + /// - a pattern with implicit derefs (thanks to default binding + /// modes #42640) may look like `Some(x)` but in fact have + /// implicit deref patterns attached (e.g., it is really + /// `&Some(x)`). In that case, we return the "outermost" type + /// (e.g., `&Option). fn pat_ty(&self, pat: &hir::Pat) -> McResult> { + // Check for implicit `&` types wrapping the pattern; note + // that these are never attached to binding patterns, so + // actually this is somewhat "disjoint" from the code below + // that aims to account for `ref x`. + if let Some(vec) = self.tables.pat_adjustments().get(pat.hir_id) { + if let Some(first_ty) = vec.first() { + debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty); + return Ok(first_ty); + } + } + + self.pat_ty_unadjusted(pat) + } + + + /// Like `pat_ty`, but ignores implicit `&` patterns. + fn pat_ty_unadjusted(&self, pat: &hir::Pat) -> McResult> { let base_ty = self.node_ty(pat.hir_id)?; + debug!("pat_ty(pat={:?}) base_ty={:?}", pat, base_ty); + // This code detects whether we are looking at a `ref x`, // and if so, figures out what the type *being borrowed* is. let ret_ty = match pat.node { @@ -531,8 +560,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } _ => base_ty, }; - debug!("pat_ty(pat={:?}) base_ty={:?} ret_ty={:?}", - pat, base_ty, ret_ty); + debug!("pat_ty(pat={:?}) ret_ty={:?}", pat, ret_ty); + Ok(ret_ty) } @@ -1246,7 +1275,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { self.tcx.adt_def(enum_def).variant_with_id(def_id).fields.len()) } Def::StructCtor(_, CtorKind::Fn) => { - match self.pat_ty(&pat)?.sty { + match self.pat_ty_unadjusted(&pat)?.sty { ty::TyAdt(adt_def, _) => { (cmt, adt_def.non_enum_variant().fields.len()) } @@ -1297,7 +1326,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { PatKind::Tuple(ref subpats, ddpos) => { // (p1, ..., pN) - let expected_len = match self.pat_ty(&pat)?.sty { + let expected_len = match self.pat_ty_unadjusted(&pat)?.sty { ty::TyTuple(ref tys) => tys.len(), ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), }; diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d2bde14732bbc..2af4c3f9fd463 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -378,7 +378,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } for param in generics.types.iter() { - let name = param.name.as_str().to_string(); + let name = param.name.to_string(); let ty = trait_ref.substs.type_for_def(param); let ty_str = ty.to_string(); flags.push((name.clone(), diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 8c2c1cfa45472..f7ce55c2e1df2 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -289,7 +289,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { let trait_str = tcx.item_path_str(trait_ref.def_id); let generics = tcx.generics_of(trait_ref.def_id); let generic_map = generics.types.iter().map(|param| { - (param.name.as_str().to_string(), + (param.name.to_string(), trait_ref.substs.type_for_def(param).to_string()) }).collect::>(); diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 93ae101eb1426..4f4ea52275955 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -959,11 +959,21 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { if self.can_use_global_caches(param_env) { let mut cache = self.tcx().evaluation_cache.hashmap.borrow_mut(); if let Some(trait_ref) = self.tcx().lift_to_global(&trait_ref) { + debug!( + "insert_evaluation_cache(trait_ref={:?}, candidate={:?}) global", + trait_ref, + result, + ); cache.insert(trait_ref, WithDepNode::new(dep_node, result)); return; } } + debug!( + "insert_evaluation_cache(trait_ref={:?}, candidate={:?})", + trait_ref, + result, + ); self.infcx.evaluation_cache.hashmap .borrow_mut() .insert(trait_ref, WithDepNode::new(dep_node, result)); @@ -1067,25 +1077,29 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { if self.intercrate_ambiguity_causes.is_some() { debug!("evaluate_stack: intercrate_ambiguity_causes is some"); // Heuristics: show the diagnostics when there are no candidates in crate. - let candidate_set = self.assemble_candidates(stack)?; - if !candidate_set.ambiguous && candidate_set.vec.iter().all(|c| { - !self.evaluate_candidate(stack, &c).may_apply() - }) { - let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; - let self_ty = trait_ref.self_ty(); - let trait_desc = trait_ref.to_string(); - let self_desc = if self_ty.has_concrete_skeleton() { - Some(self_ty.to_string()) - } else { - None - }; - let cause = if let Conflict::Upstream = conflict { - IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } - } else { - IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } - }; - debug!("evaluate_stack: pushing cause = {:?}", cause); - self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause); + if let Ok(candidate_set) = self.assemble_candidates(stack) { + if !candidate_set.ambiguous && candidate_set.vec.iter().all(|c| { + !self.evaluate_candidate(stack, &c).may_apply() + }) { + let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; + let self_ty = trait_ref.self_ty(); + let trait_desc = trait_ref.to_string(); + let self_desc = if self_ty.has_concrete_skeleton() { + Some(self_ty.to_string()) + } else { + None + }; + let cause = if let Conflict::Upstream = conflict { + IntercrateAmbiguityCause::UpstreamCrateUpdate { + trait_desc, + self_desc, + } + } else { + IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } + }; + debug!("evaluate_stack: pushing cause = {:?}", cause); + self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause); + } } } return Ok(None); @@ -1283,12 +1297,22 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let mut cache = tcx.selection_cache.hashmap.borrow_mut(); if let Some(trait_ref) = tcx.lift_to_global(&trait_ref) { if let Some(candidate) = tcx.lift_to_global(&candidate) { + debug!( + "insert_candidate_cache(trait_ref={:?}, candidate={:?}) global", + trait_ref, + candidate, + ); cache.insert(trait_ref, WithDepNode::new(dep_node, candidate)); return; } } } + debug!( + "insert_candidate_cache(trait_ref={:?}, candidate={:?}) local", + trait_ref, + candidate, + ); self.infcx.selection_cache.hashmap .borrow_mut() .insert(trait_ref, WithDepNode::new(dep_node, candidate)); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b6b38c76a2978..d0bb30e3201f5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -70,11 +70,11 @@ use std::iter; use std::sync::mpsc; use std::sync::Arc; use syntax::abi; -use syntax::ast::{self, Name, NodeId}; +use syntax::ast::{self, NodeId}; use syntax::attr; use syntax::codemap::MultiSpan; use syntax::feature_gate; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::{Symbol, keywords, InternedString}; use syntax_pos::Span; use hir; @@ -2256,12 +2256,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn mk_param(self, index: u32, - name: Name) -> Ty<'tcx> { + name: InternedString) -> Ty<'tcx> { self.mk_ty(TyParam(ParamTy { idx: index, name: name })) } pub fn mk_self_type(self) -> Ty<'tcx> { - self.mk_param(0, keywords::SelfType.name()) + self.mk_param(0, keywords::SelfType.name().as_str()) } pub fn mk_param_from_def(self, def: &ty::TypeParameterDef) -> Ty<'tcx> { diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 5f9c305d92f04..208d61032861f 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1677,18 +1677,19 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } } - let discr = Scalar { + let tag_mask = !0u128 >> (128 - ity.size().bits()); + let tag = Scalar { value: Int(ity, signed), - valid_range: (min as u128)..=(max as u128) + valid_range: (min as u128 & tag_mask)..=(max as u128 & tag_mask), }; - let abi = if discr.value.size(dl) == size { - Abi::Scalar(discr.clone()) + let abi = if tag.value.size(dl) == size { + Abi::Scalar(tag.clone()) } else { Abi::Aggregate { sized: true } }; tcx.intern_layout(LayoutDetails { variants: Variants::Tagged { - discr, + discr: tag, variants }, fields: FieldPlacement::Arbitrary { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 72ba199eb2412..43c5ba46b44c9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -712,7 +712,7 @@ pub struct FloatVarValue(pub ast::FloatTy); #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] pub struct TypeParameterDef { - pub name: Name, + pub name: InternedString, pub def_id: DefId, pub index: u32, pub has_default: bool, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index ed04d41ba1457..425ab1a312a70 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -24,7 +24,7 @@ use std::iter; use std::cmp::Ordering; use syntax::abi; use syntax::ast::{self, Name}; -use syntax::symbol::keywords; +use syntax::symbol::{keywords, InternedString}; use serialize; @@ -864,16 +864,16 @@ impl<'tcx> PolyFnSig<'tcx> { #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub struct ParamTy { pub idx: u32, - pub name: Name, + pub name: InternedString, } impl<'a, 'gcx, 'tcx> ParamTy { - pub fn new(index: u32, name: Name) -> ParamTy { + pub fn new(index: u32, name: InternedString) -> ParamTy { ParamTy { idx: index, name: name } } pub fn for_self() -> ParamTy { - ParamTy::new(0, keywords::SelfType.name()) + ParamTy::new(0, keywords::SelfType.name().as_str()) } pub fn for_def(def: &ty::TypeParameterDef) -> ParamTy { @@ -885,8 +885,10 @@ impl<'a, 'gcx, 'tcx> ParamTy { } pub fn is_self(&self) -> bool { - if self.name == keywords::SelfType.name() { - assert_eq!(self.idx, 0); + // FIXME(#50125): Ignoring `Self` with `idx != 0` might lead to weird behavior elsewhere, + // but this should only be possible when using `-Z continue-parse-after-error` like + // `compile-fail/issue-36638.rs`. + if self.name == keywords::SelfType.name().as_str() && self.idx == 0 { true } else { false diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index afe977d10baac..f6d29592d427c 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -722,7 +722,7 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> } TyParam(p) => { self.hash(p.idx); - self.hash(p.name.as_str()); + self.hash(p.name); } TyProjection(ref data) => { self.def_id(data.item_def_id); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 9efd8844977f9..971855ee2d007 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -303,7 +303,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { pub fn t_param(&self, index: u32) -> Ty<'tcx> { let name = format!("T{}", index); - self.infcx.tcx.mk_param(index, Symbol::intern(&name)) + self.infcx.tcx.mk_param(index, Symbol::intern(&name).as_str()) } pub fn re_early_bound(&self, index: u32, name: &'static str) -> ty::Region<'tcx> { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 5fd8ebaa9b4a6..5640212131234 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -163,7 +163,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, fn_arg_names => { cdata.get_fn_arg_names(def_id.index) } impl_parent => { cdata.get_parent_impl(def_id.index) } trait_of_item => { cdata.get_trait_of_item(def_id.index) } - item_body_nested_bodies => { cdata.item_body_nested_bodies(def_id.index) } + item_body_nested_bodies => { cdata.item_body_nested_bodies(tcx, def_id.index) } const_is_rvalue_promotable_to_static => { cdata.const_is_rvalue_promotable_to_static(def_id.index) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 20e2ada5bd9b3..6987389dca8b2 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -817,11 +817,14 @@ impl<'a, 'tcx> CrateMetadata { tcx.alloc_tables(ast.tables.decode((self, tcx))) } - pub fn item_body_nested_bodies(&self, id: DefIndex) -> ExternBodyNestedBodies { + pub fn item_body_nested_bodies(&self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + id: DefIndex) + -> ExternBodyNestedBodies { if let Some(ref ast) = self.entry(id).ast { - let ast = ast.decode(self); + let mut ast = ast.decode(self); let nested_bodies: BTreeMap<_, _> = ast.nested_bodies - .decode(self) + .decode((self, tcx.sess)) .map(|body| (body.id(), body)) .collect(); ExternBodyNestedBodies { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index f71b06e4ddf3f..7905fe998efc2 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -212,8 +212,6 @@ use monomorphize::item::{MonoItemExt, DefPathBasedNames, InstantiationMode}; use rustc_data_structures::bitvec::BitVector; -use std::iter; - #[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] pub enum MonoItemCollectionMode { Eager, @@ -1030,13 +1028,15 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> { // late-bound regions, since late-bound // regions must appear in the argument // listing. - let main_ret_ty = main_ret_ty.no_late_bound_regions().unwrap(); + let main_ret_ty = self.tcx.erase_regions( + &main_ret_ty.no_late_bound_regions().unwrap(), + ); let start_instance = Instance::resolve( self.tcx, ty::ParamEnv::reveal_all(), start_def_id, - self.tcx.mk_substs(iter::once(Kind::from(main_ret_ty))) + self.tcx.intern_substs(&[Kind::from(main_ret_ty)]) ).unwrap(); self.output.push(create_fn_mono_item(start_instance)); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 7ab3499ead369..a513ebbf6c7f4 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -82,7 +82,6 @@ use std::str; use std::sync::Arc; use std::time::{Instant, Duration}; use std::{i32, usize}; -use std::iter; use std::sync::mpsc; use syntax_pos::Span; use syntax_pos::symbol::InternedString; @@ -553,7 +552,9 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) { // late-bound regions, since late-bound // regions must appear in the argument // listing. - let main_ret_ty = main_ret_ty.no_late_bound_regions().unwrap(); + let main_ret_ty = cx.tcx.erase_regions( + &main_ret_ty.no_late_bound_regions().unwrap(), + ); if declare::get_defined_value(cx, "main").is_some() { // FIXME: We should be smart and show a better diagnostic here. @@ -580,8 +581,11 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) { let (start_fn, args) = if use_start_lang_item { let start_def_id = cx.tcx.require_lang_item(StartFnLangItem); - let start_fn = callee::resolve_and_get_fn(cx, start_def_id, cx.tcx.mk_substs( - iter::once(Kind::from(main_ret_ty)))); + let start_fn = callee::resolve_and_get_fn( + cx, + start_def_id, + cx.tcx.intern_substs(&[Kind::from(main_ret_ty)]), + ); (start_fn, vec![bx.pointercast(rust_main, Type::i8p(cx).ptr_to()), arg_argc, arg_argv]) } else { diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 762e705e7ed32..ba0dc8f20f802 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -43,7 +43,7 @@ use std::ptr; use syntax_pos::{self, Span, Pos}; use syntax::ast; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, InternedString}; use rustc::ty::layout::{self, LayoutOf}; pub mod gdb; @@ -394,7 +394,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, substs.types().zip(names).map(|(ty, name)| { let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); - let name = CString::new(name.as_str().as_bytes()).unwrap(); + let name = CString::new(name.as_bytes()).unwrap(); unsafe { llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), @@ -413,7 +413,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, return create_DIArray(DIB(cx), &template_params[..]); } - fn get_type_parameter_names(cx: &CodegenCx, generics: &ty::Generics) -> Vec { + fn get_type_parameter_names(cx: &CodegenCx, generics: &ty::Generics) -> Vec { let mut names = generics.parent.map_or(vec![], |def_id| { get_type_parameter_names(cx, cx.tcx.generics_of(def_id)) }); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0e93277983f8d..c4ea543ab36b6 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -979,7 +979,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let item_def_id = tcx.hir.local_def_id(item_id); let generics = tcx.generics_of(item_def_id); let index = generics.type_param_to_index[&tcx.hir.local_def_id(node_id)]; - tcx.mk_param(index, tcx.hir.name(node_id)) + tcx.mk_param(index, tcx.hir.name(node_id).as_str()) } Def::SelfTy(_, Some(def_id)) => { // Self in impl (we know the concrete type). diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 377e3a891840f..da0d4509353b5 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -76,7 +76,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// and in libcore/intrinsics.rs pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::ForeignItem) { - let param = |n| tcx.mk_param(n, Symbol::intern(&format!("P{}", n))); + let param = |n| tcx.mk_param(n, Symbol::intern(&format!("P{}", n)).as_str()); let name = it.name.as_str(); let (n_tps, inputs, output) = if name.starts_with("atomic_") { let split : Vec<&str> = name.split('_').collect(); @@ -341,7 +341,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::ForeignItem) { let param = |n| { - let name = Symbol::intern(&format!("P{}", n)); + let name = Symbol::intern(&format!("P{}", n)).as_str(); tcx.mk_param(n, name) }; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 7dc73a1d5f019..6348f3861770f 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -655,7 +655,7 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) { // local so it should be okay to just unwrap everything. let trait_def_id = impl_params[&method_param.name]; let trait_decl_span = tcx.def_span(trait_def_id); - error_194(tcx, type_span, trait_decl_span, method_param.name); + error_194(tcx, type_span, trait_decl_span, &method_param.name[..]); } } } @@ -759,7 +759,7 @@ fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast: err } -fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: ast::Name) { +fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: &str) { struct_span_err!(tcx.sess, span, E0194, "type parameter `{}` shadows another type parameter of the same name", name) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b2bc5114034d5..07f4a13a197ce 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -241,7 +241,7 @@ fn type_param_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let param_owner_def_id = tcx.hir.local_def_id(param_owner); let generics = tcx.generics_of(param_owner_def_id); let index = generics.type_param_to_index[&def_id]; - let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id)); + let ty = tcx.mk_param(index, tcx.hir.ty_param_name(param_id).as_str()); // Don't look for bounds where the type parameter isn't in scope. let parent = if item_def_id == param_owner_def_id { @@ -839,7 +839,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, opt_self = Some(ty::TypeParameterDef { index: 0, - name: keywords::SelfType.name(), + name: keywords::SelfType.name().as_str(), def_id: tcx.hir.local_def_id(param_id), has_default: false, object_lifetime_default: rl::Set1::Empty, @@ -915,7 +915,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TypeParameterDef { index: type_start + i as u32, - name: p.name, + name: p.name.as_str(), def_id: tcx.hir.local_def_id(p.id), has_default: p.default.is_some(), object_lifetime_default: @@ -934,7 +934,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // add a dummy parameter for the closure kind types.push(ty::TypeParameterDef { index: type_start, - name: Symbol::intern(""), + name: Symbol::intern("").as_str(), def_id, has_default: false, object_lifetime_default: rl::Set1::Empty, @@ -945,7 +945,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // add a dummy parameter for the closure signature types.push(ty::TypeParameterDef { index: type_start + 1, - name: Symbol::intern(""), + name: Symbol::intern("").as_str(), def_id, has_default: false, object_lifetime_default: rl::Set1::Empty, @@ -956,7 +956,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.with_freevars(node_id, |fv| { types.extend(fv.iter().zip(2..).map(|(_, i)| ty::TypeParameterDef { index: type_start + i, - name: Symbol::intern(""), + name: Symbol::intern("").as_str(), def_id, has_default: false, object_lifetime_default: rl::Set1::Empty, @@ -1436,7 +1436,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Collect the predicates that were written inline by the user on each // type parameter (e.g., ``). for param in ast_generics.ty_params() { - let param_ty = ty::ParamTy::new(index, param.name).to_ty(tcx); + let param_ty = ty::ParamTy::new(index, param.name.as_str()).to_ty(tcx); index += 1; let bounds = compute_bounds(&icx, diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index fe4f785aa915e..89fbe1b72ea11 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -260,7 +260,9 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { P(hir::Path { span: DUMMY_SP, def: Def::TyParam(param.def_id), - segments: HirVec::from_vec(vec![hir::PathSegment::from_name(param.name)]), + segments: HirVec::from_vec(vec![ + hir::PathSegment::from_name(Symbol::intern(¶m.name)) + ]), }), )), span: DUMMY_SP, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index e3ba482eecfee..f63c20fb37e92 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -27,7 +27,7 @@ use syntax::codemap::Spanned; use syntax::feature_gate::UnstableFeatures; use syntax::ptr::P; use syntax::symbol::keywords; -use syntax::symbol::Symbol; +use syntax::symbol::{Symbol, InternedString}; use syntax_pos::{self, DUMMY_SP, Pos, FileName}; use rustc::middle::const_val::ConstVal; @@ -1769,7 +1769,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, // predicates field (see rustc_typeck::collect::ty_generics), so remove // them. let stripped_typarams = gens.types.iter().filter_map(|tp| { - if tp.name == keywords::SelfType.name() { + if tp.name == keywords::SelfType.name().as_str() { assert_eq!(tp.index, 0); None } else { @@ -3349,6 +3349,12 @@ impl Clean for ast::Name { } } +impl Clean for InternedString { + fn clean(&self, _: &DocContext) -> String { + self.to_string() + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Typedef { pub type_: Type, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 71609af803e09..25b392433ec57 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -382,12 +382,6 @@ declare_features! ( // Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008) (active, non_exhaustive, "1.22.0", Some(44109), None), - // allow `'_` placeholder lifetimes - (active, underscore_lifetimes, "1.22.0", Some(44524), None), - - // Default match binding modes (RFC 2005) - (active, match_default_bindings, "1.22.0", Some(42640), None), - // Trait object syntax with `dyn` prefix (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)), diff --git a/src/test/compile-fail/issue-47715.rs b/src/test/compile-fail/issue-47715.rs new file mode 100644 index 0000000000000..b6b720f088aee --- /dev/null +++ b/src/test/compile-fail/issue-47715.rs @@ -0,0 +1,38 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo {} + +trait Bar {} + +trait Iterable { + type Item; +} + +struct Container> { + //~^ ERROR `impl Trait` not allowed + field: T +} + +enum Enum> { + //~^ ERROR `impl Trait` not allowed + A(T), +} + +union Union + Copy> { + //~^ ERROR `impl Trait` not allowed + x: T, +} + +type Type> = T; +//~^ ERROR `impl Trait` not allowed + +fn main() { +} diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs new file mode 100644 index 0000000000000..bd6bcf88a0caf --- /dev/null +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully +// failure-status: 1 + +#![feature(dyn_trait)] + +use std::error::Error; +use std::io; + +fn main() -> Result<(), Box> { + Err(Box::new(io::Error::new(io::ErrorKind::Other, "returned Box from main()"))) +} diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-str.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-str.rs new file mode 100644 index 0000000000000..9f01b0bff8955 --- /dev/null +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-str.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern: An error message for you +// failure-status: 1 + +fn main() -> Result<(), &'static str> { + Err("An error message for you") +} diff --git a/src/test/run-pass/issue-49556.rs b/src/test/run-pass/issue-49556.rs new file mode 100644 index 0000000000000..70ccee99f664d --- /dev/null +++ b/src/test/run-pass/issue-49556.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn iter<'a>(data: &'a [usize]) -> impl Iterator + 'a { + data.iter() + .map( + |x| x // fn(&'a usize) -> &'(ReScope) usize + ) + .map( + |x| *x // fn(&'(ReScope) usize) -> usize + ) +} + +fn main() { +} diff --git a/src/test/run-pass/issue-49973.rs b/src/test/run-pass/issue-49973.rs new file mode 100644 index 0000000000000..641e9239177fb --- /dev/null +++ b/src/test/run-pass/issue-49973.rs @@ -0,0 +1,20 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[derive(Debug)] +#[repr(i32)] +enum E { + Min = -2147483648i32, + _Max = 2147483647i32, +} + +fn main() { + assert_eq!(Some(E::Min).unwrap() as i32, -2147483648i32); +} diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs new file mode 100644 index 0000000000000..24c30a5abc22a --- /dev/null +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-box-dyn-error.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(dyn_trait)] + +use std::error::Error; + +fn main() -> Result<(), Box> { + Ok(()) +} diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-str.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-str.rs new file mode 100644 index 0000000000000..2023ff75564f7 --- /dev/null +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-str.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() -> Result<(), &'static str> { + Ok(()) +} diff --git a/src/test/ui/issue-48728.rs b/src/test/ui/issue-48728.rs new file mode 100644 index 0000000000000..251ebf5d418b0 --- /dev/null +++ b/src/test/ui/issue-48728.rs @@ -0,0 +1,23 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for #48728, an ICE that occurred computing +// coherence "help" information. + +#[derive(Clone)] //~ ERROR conflicting implementations of trait `std::clone::Clone` +struct Node(Box); + +impl Clone for Node<[T]> { + fn clone(&self) -> Self { + Node(Box::clone(&self.0)) + } +} + +fn main() {} diff --git a/src/test/ui/issue-48728.stderr b/src/test/ui/issue-48728.stderr new file mode 100644 index 0000000000000..05c87fe66ee85 --- /dev/null +++ b/src/test/ui/issue-48728.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Node<[_]>`: + --> $DIR/issue-48728.rs:14:10 + | +LL | #[derive(Clone)] //~ ERROR conflicting implementations of trait `std::clone::Clone` + | ^^^^^ conflicting implementation for `Node<[_]>` +... +LL | impl Clone for Node<[T]> { + | ------------------------------------------- first implementation here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs b/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs new file mode 100644 index 0000000000000..8dc1627dc8b5a --- /dev/null +++ b/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.rs @@ -0,0 +1,34 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct Foo { +} + +impl Foo { + fn get(&self) -> Option<&Result> { + None + } + + fn mutate(&mut self) { } +} + +fn main() { + let mut foo = Foo { }; + + // foo.get() returns type Option<&Result>, so + // using `string` keeps borrow of `foo` alive. Hence calling + // `foo.mutate()` should be an error. + while let Some(Ok(string)) = foo.get() { + foo.mutate(); + //~^ ERROR cannot borrow `foo` as mutable + println!("foo={:?}", *string); + } +} diff --git a/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.stderr b/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.stderr new file mode 100644 index 0000000000000..2da5ac8d240bf --- /dev/null +++ b/src/test/ui/rfc-2005-default-binding-mode/borrowck-issue-49631.stderr @@ -0,0 +1,13 @@ +error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable + --> $DIR/borrowck-issue-49631.rs:30:9 + | +LL | while let Some(Ok(string)) = foo.get() { + | --- - immutable borrow ends here + | | + | immutable borrow occurs here +LL | foo.mutate(); + | ^^^ mutable borrow occurs here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/tools/rustfmt b/src/tools/rustfmt index a4462d18bf6b9..7a80726258d38 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit a4462d18bf6b92aaec1eeb1c30d5ddf94a3ca987 +Subproject commit 7a80726258d38b91ebb12144a2c2dd5d422cdfa8